- スコープと存在
- 静的スコープと動的スコープ
- グローバルスコープ
- ブロックスコープ
- 変数の隠蔽
- 関数、クロージャ、静的スコープ
- IIFE(即座に実行される関数)
- 関数のスコープと巻き上げ
- 関数の巻き上げ
- TDZ(Temporal Dead Zone)
- strictモード
- 参考文献
- 変数、定数、引数が有効な範囲を決めるモノ
スコープと存在
- 変数などがプログラム中で存在している状態ではなくなっても、
JavaScript
がその分のメモリをすぐに回収するとは限りません。- その変数に対し、管理の必要がなくなったことを記録するだけ。
- 実際のメモリ回収は「ガベージコレクション」によって定期的に行われる。
静的スコープと動的スコープ
JavaScript
の構文は静的スコープ(構文スコープ:lexicsl scope)
const x = 3; function f (){ console.log(x); // xを参照可能 } f();
グローバルスコープ
- プログラムが実行を開始する際に暗黙的に存在するスコープ
- 大域スコープともいう
- JavaScriptのプログラムが実行を開始し、関数を呼び出す前にはグローバルスコープで実行される。
ブロックスコープ
- ブロックスコープで定義された識別子はそれを囲むブロックでしか有効になりません。
変数の隠蔽
- 同じ名前の変数や定数が異なるスコープで使用され、かつそれぞれのスコープが重複する部分がある場合は後から定義された変数が有効になり、元から定義されている変数へのアクセスができなくなる
{ let x = 3; console.log(x); { let x = 5; console.log(x); } console.log(x); }
関数、クロージャ、静的スコープ
- 関数の周囲にスクープを閉じこむもの
let func; { let o = {memo1:"安全", memo2:"大丈夫!"}; func = function(){ console.log(`無名関数の中:${o.memo1}`); //無名関数の中:安全 return o; } } let oRes = func(); console.log(oRes); // {memo1: "安全", memo2: "大丈夫!"} oRes.memo1 = "危険"; console.log(oRes); // {memo1: "危険", memo2: "大丈夫!"}
IIFE(即座に実行される関数)
- 関数式(IIFE:immediately invoked function expression)
- 即時関数ともいう
- 関数を宣言するとすぐに実行する
(function(){ // IIFEの本体 })();
メリット
- 独自のスコープを持つ
- スコープ内部の情報を外部に渡す(return
する)ことができる。
関数のスコープと巻き上げ
var
を使って宣言した変数には「巻き上げ」が発生する。- スコープ全体で
var
で宣言された同じ名前の変数があれば、それが使われている個所で宣言されたものとして扱う
- スコープ全体で
{ console.log(x); // undefined var x = 5; console.log(x); // x }
var x ~
は最初にx
が実行されるより後に記述されているが、「巻き上げ」が実施されるため、宣言済み扱いになる。
関数の巻き上げ
var
を使用すると関数宣言もスコープの先頭に巻き上げられる。
TDZ(Temporal Dead Zone)
let
で宣言された変数は宣言されるまで存在しないということ
strictモード
'use strict'
、または"use strict"
を記述することで、暗黙的グローバルが禁止される。- グローバルスコープの他の文の前にあれば、スコープ全体が
strictモード
で実行される - 関数内の他の文の前にあれば、その関数が
strictモード
で実行される
- グローバルスコープの他の文の前にあれば、スコープ全体が