funacchi.qrunch.io読者になる1【要約-改訂新版JavaScript本格入門】関数について3JavaScript投稿日:2019-07-31最終更新:2019-08-22筆者のブログで記事をみる以下の続きである。-スコープ-スコープとは「変数がスクリプトの中のどの場所から参照できるかを決める」概念。(=変数が使用できる有効範囲)JavaScriptのスコープは以下2つに分類される。グローバルスコープスクリプト全体から参照できるローカルスコープ定義された関数内でのみ参照できる※ES2015からは「ブロックスコープ」という概念が追加された。Variableスコープが異なる場合、それぞれの変数は同名であっても別物として認識される。変数宣言にvar命令が必須な理由var命令を使わずに宣言された変数は、以下のようにすべてグローバル変数として扱われる。Variableつまり、ローカル変数を定義するためには必ずvar命令を使用する必要がある。「グローバル変数にはvar命令をつけずにローカル変数にはvar命令をつける」というのは混乱のもとになるため、原則としてvar命令は省略すべきではない。ローカル変数の有効範囲はどこまで変数の巻き上げについて関数内で宣言されたローカル変数は、変数の巻き上げにより、その関数の先頭で宣言したものとみなされる。巻き上げられるのは宣言部分のみであり、中身の代入が行われていないため、下記のコードのように意図しない結果を生み出す可能性がある。防止策としてローカル変数は関数の先頭で宣言すること。上記の文は以下と同じである。-基本型と参照型の違いに注意する-以下のように、仮引数は「基本的に」ローカル変数として処理される。グローバル変数は仮引数の影響を受けずに10と出力されるただし、参照型の値を仮引数として渡す場合は上記と挙動が変わる。4]と出力されるなぜなら、参照型は値そのものではなく、値を格納したメモリ上のアドレスだけを格納しており、参照型の値を渡す場合にも渡される情報はメモリ上のアドレスとなるため。ブロックレベルのスコープは存在しない(ES2015以前)JavaやC#のような言語の場合、以下のコードではエラーが発生する。System.out.println(i);しかし、JavaScriptでは、ブロックレベルのスコープは存在しないため、同様のコードは成立する。5即時関数で変数名の競合を防ぐ関数によってスコープが決まるなら、関数をスコープの枠組みとして利用する方法。definedアプリを作る場合、コード全体を即時関数でくくることで、アプリ以外のコード(例えばライブラリなど)と変数名が競合する心配がなくなる。ブロックスコープに対応したlet命令ES2015で追加されたlet命令は、ブロックスコープに対応した変数を宣言できる。const命令で定義された定数も同様にブロックスコープを持つ。「スコープはできる限り限定すべき」という一般的なプログラミングルールにのっとれば、ES2015が利用できる環境ではvar命令ではなくlet命令を使用すべき。definedlet命令を用いた上記コードと前項で触れた即時関数を使用したコードは同じ結果が得られる。即時関数よりもlet命令を使用した方がコードがシンプルになるため、ES2015環境ではlet命令を使用すること。関数リテラル/Functionコンストラクタにおけるスコープの違い関数の中で使用した場合、関数リテラルとFunctionコンストラクターでは、以下のようにスコープの解釈が異なる。check();Functionコンストラクタ配下の変数は、その宣言場所にかかわらず、常にグローバルスコープとみなされる。混乱を避けるため、前項4.1.2で記述した通り、原則Functionコンストラクターは使用しない方がよい。funacchi.qrunch.iofunacchiの技術ブログ。Qrunch.netサーバー提供フィードバックを送信する。