質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
スコープ

スコープとは、プログラム内で変数名など、参照可能な有効範囲のことを指します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

3816閲覧

『JavaScript』スコープ外からの参照ができない件について

pillow_545

総合スコア13

スコープ

スコープとは、プログラム内で変数名など、参照可能な有効範囲のことを指します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/12/22 12:49

前提・実現したいこと

配列'responders_name'の中にpushした内容をスコープ外で参照したいのですが、できずに困っています。
JavaScriptではスコープ外から参照できない決まりでもあるのかな? と考えましたが、そうではない様子。

該当のソースコード

JavaScript

1 2 responders.forEach(async (element) => { 3 pre = await client.query(`SELECT * FROM users WHERE id = '${element}'`); 4 responders_name.push(pre.rows[0].user_name); 5 console.log("forEachの中です", responders_name); 6 }); 7 8 console.log("forEachの外です",responders_name) 9 10 11出力結果: 12forEachの外です [] 13forEachの中です [ '回答者A' ] 14forEachの中です [ '回答者A', '回答者B' ] 15forEachの中です [ '回答者A', '回答者B', '回答者C' ] 16 17 18 19 20 21

試したこと

1行目の文頭にawaitを書いてみる(効果なし)

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

スコープは関係ない。
結果の出力順を見ると、「外です」が「中です」より先に出力されているだろう。
そして、「中です」は変数responders_nameへのpushとほぼ同時に行われている。
つまり、「外です」の出力時には、まだresponders_nameへのpushが行われていない。だから何も出力されない。

何故そうなるかというと、foreachに渡されている関数がasyncだからだ。
responders_name.push は、client.query の実行終了を待つ(await)が、外のconsole.logはresponders.forEachに渡されているasync関数の終了を待たない。

ちなみに、提示されたコードでは responders_name のスコープが不明瞭だが、本当にコードがその通り(つまり変数宣言が存在しない)ならば、 responders_name はグローバル変数=プログラムの全域で参照・書き換えが可能な変数であり、外のconsole.logも普通にスコープ内だ。
(実際には空配列で初期化しているようなので、変数宣言もどこかにあるのだろうが)

そもそも「スコープ」とは「変数を参照可能な範囲」という意味なので、「スコープの外で変数を参照できない」は「変数を参照可能な範囲の外で変数を参照できない」という意味になり、「そりゃそうじゃ」という感じなのだが、スコープという単語の意味を何か誤解してはいないだろうか。

投稿2020/12/22 13:12

fukken

総合スコア73

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まずなんでも async/await をつけるのをやめましょう。必要なところにのみつけるべきです。あと変数宣言には letconst を書きましょう。

で、本題ですが配列から新しい配列を得たい場合 mapreduce が使える場合があります。今回の場合は map で十分と思われますので使ってみましょう。ちなみに外の変数からでも参照はできます。

投稿2020/12/22 12:56

A_kirisaki

総合スコア2853

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問