##概要
var、let、constの3種類の違いと、それぞれのスコープ内の挙動に関してまとめました。
先に押さえておきたい部分を説明した後に、スコープの説明に入ります。
##目次
- 変数
- 変数宣言
- 変数宣言の種類
- 変数宣言
- 初期化と代入
- 初期化
- 代入
- スコープ
- スコープの種類
- グローバルスコープ
- ローカルスコープ
- 関数スコープ
- ブロックスコープ
- スコープチェーン
- スコープの種類
##変数
扱いたいデータを格納し、何度でも再利用できるオブジェクト。
###変数宣言
変数をプログラム上に定義すること。
####変数宣言の種類
変数宣言には以下の種類が存在し、それぞれ挙動が異なる。
#####var(バー)
古くから使われているお馴染みの変数宣言、jQueryのサンプルなどもほとんどvarが使用されている。
実案件でも世に溢れているので必ず理解していないとまずい。
#####let(レト)
ES6から登場した変数宣言、代入可能なのでvarに近い感覚で使える。
#####const(コンスト)
ES6から登場した変数宣言、再代入不可なので、定数の感覚で使える。
※let、constはES6だけどIE11に対応しているのでそのまま使用できる。
##初期化と代入
###初期化
変数宣言と同時に、値・文字列を代入すること。
var x = 0;
###代入
すでに定義されている変数に、値・文字列を格納すること。
var x = 0;
x = 1;
####varにおける注意点
初期化が何度でも可能であるので、代入と混乱しないように注意したい。
#####■間違い
var x = 0;
var x = 1;
このように初期化して上書きしてもエラーにならない、これをlet、constで実行するとエラーになる。
#####■正しい
var x = 0;
x = 1;
##スコープ
定義した変数を参照できる範囲。
###スコープの種類
グローバルスコープとローカルスコープが存在する、さらにローカルスコープとして関数スコープとブロックスコープが存在する。
####グローバルスコープ
scriptタグ内の最も外側のエリア、ここで宣言された変数はwindowオブジェクト直下に格納される。
このエリアに定義されている変数をグローバル変数と呼ぶ。
var x = 0;
console.log(window.x);
// 0
####ローカルスコープ
グローバルスコープの内側で、より参照範囲を絞ったスコープ。
ローカルスコープとして関数スコープ、ブロックスコープが存在する。
このエリアに定義されている変数をローカル変数と呼ぶ。
####関数スコープ
関数内に存在するスコープ。
function myFunc() {
var x = 0;
console.log(x);
// 0
};
myFunc();
console.log(x); // ReferenceError
#####引数がある場合の注意点
関数において、引数はローカル変数である。
外側のスコープを見ているのかと思えば、引数がある場合は同スコープ内の変数として扱われるので注意。
var x = 0;
function myFunc(x) {
console.log(x);
};
myFunc(1);
// 1
####ブロックスコープ
ブロック内に存在するスコープ
※変数宣言はlet、constのみ対応。
{
let x = 0;
console.log(x);
// 0
}
console.log(x); // ReferenceError
varはブロックスコープに対応していない。
{
var x = 0;
console.log(x);
// 0
}
console.log(x);
// 0
#####ローカルスコープ内での変数宣言対応を一覧表にしました。
######関数スコープ
var | let | const |
---|---|---|
○ | ○ | ○ |
######ブロックスコープ
var | let | const |
---|---|---|
× | ○ | ○ |
※スコープに適応している場合○、しない場合×
#####例外ケース
for文の()にもローカルスコープに等しい挙動がある、for文のブロック外からは参照できない。
for(let x = 0;x < 10;x++){
console.log(x);
// 0〜9
}
console.log(x);
// ReferenceError
###スコープチェーン
スコープチェーンとは、複数生成されたオブジェクトに対して、それらの順序をリスト化したものである。
生成されたオブジェクトにスコープが存在するので、変数はどの順序で参照していくのか仕組みを理解する必要がある。
スコープチェーンの仕組みを知らないと、特にスコープがネストされている際に変数の参照を正しく判別できない。
以下のコードと文脈で説明します。
function outerFunc() {
var x = 0;
function innerFunc() {
var z = 2;
console.log(x);
console.log(y);
console.log(z);
};
innerFunc();
};
var y = 1;
outerFunc();
// 0
// 1
// 2
- xはinnerFunc内を探したが、存在しなかったので一つ上のouterFunc内を探しに行き拾えた。
- yはinnerFunc内、outerFunc内を順に探したが存在しなかった、次にグローバルスコープ内を探しに行き拾えた。
- zはinnerFunc内に存在したのでそのまま拾えた。
このように近くのスコープから順に辿り探していく仕組みである。
以上となります、ご覧戴きありがとうございました。
間違い等のご指摘あれば、よろしくお願いします。