ECMAScript6(ES6)についてゆっくり勉強 その2 let

ECMAScript6(ES6)についてゆっくり勉強 その2 let

前回のconstに引き続き、今回はletです。

今までのECMAScriptにはグローバルスコープと関数スコープしかありませんでしたが、ES6からは新たにブロックスコープが追加されました。
そのブロック内でのみ有効な変数を宣言する際に用いるのがletとなります。

言葉で説明するよりも実際のコードと値を見た方が分かりやすいんじゃないかな?
varで宣言した変数は同じ関数内では上書きされてしまっているのが分かると思います。

var v = 100; // グローバルスコープ
let l = 100; // 「グローバルブロック」スコープ

(function() {
	var v = 10; // 関数スコープ
	let l = 10; // 「関数ブロック」スコープ
	
	{
		var v = 1; // 関数スコープを上書き
		let l = 1; // ブロックスコープ
		console.log(v, l); // 1, 1
	}
	
	console.log(v, l); // 1, 10
})();

console.log(v, l); // 100, 100

ECMAScriptで変数宣言をした際にものすごく特徴的な動きをする「巻き上げ(hoisting)」ですが、letで宣言した変数の場合には巻き上げが行われません
varで宣言した変数は関数内のどこに書いてあったとしても、関数の一番最初で宣言してあるかのように振る舞います(これが「巻き上げ」です)。

(function() {
	console.log(v); // undefined
	var v = "var";
})();

上記のコードは内部的には次のようなコードとして解釈されるため、最初の出力でundefinedが出ることになります。

(function() {
	var v;
	console.log(v);
	v = "var";
})();

前述した通り、letでの変数宣言では巻き上げが行われないため、次のコードはエラーとなります。

(function() {
	console.log(l); // reference error
	let l = "let";
})();

ブロックは基本的に波括弧 { ~ } の内側で生成されますが、for文だけはちょっと特殊かもしれません。
まぁ、概ね意図通りのスコープが生成されるので問題はないと思います。

(function() {
	let i = 100;
	for(let i = 0; i < 10; i++) {
		console.log(i); // 0 ~ 9
	}
	console.log(i); // 100
})();

ですが、このfor文の後にある波括弧でもブロックスコープが生成されるので、こんな書き方をしてしまうと痛い目を見ちゃうかもしれないです。

(function() {
	let i = 100;
	for(let i = 0; i < 10; i++) {
		let i = 1000;
		console.log(i); // 1000が10回表示される
	}
	console.log(i); // 100
})();

ちなみに前回紹介したconstですが、ES6の仕様としてはブロックスコープとなっています。

{
	var foo = "foo";
	let bar = "bar";
	const baz = "baz";
	
	console.log(foo); // "foo"
	console.log(bar); // "bar"
	console.log(baz); // "baz"
}

console.log(foo); // "foo"
console.log(bar); // reference error
console.log(baz); // reference error

変数の巻き上げについての説明がちょっと長くなってしまいましたが今回はここまで!

TAG

  • このエントリーをはてなブックマークに追加
やまま
スペシャリスト やまま yamama

マンガとアニメとゲームから錬成された宇宙大好きエンジニア。 軌道エレベーターで行ける静止軌道上のコロニーに住まいを移し、ゲームやってマンガ読んでアニメ見て爆睡、ゲームやってマンガ読んでアニメ見て爆睡、という生活を夢見ながら今日もコードを書き続けるのだった。