let命令
- 識別子を「ブロックスコープ」で定義する
- ブロックスコープで定義された識別子はそれを囲むブロックでしか有効にはならない
- ブロックは通常、ifやforなどのフロー制御に関係して使われるが、独立したブロックを用いることもできる
// 基本的な宣言
let msg;
// 複数の変数を宣言
let x, y;
// 初期値を設定
let greeting = 'こんにちは、世界!';
// 独立したブロック
{
let z = 3;
console.log(z);
}
console.log(`ブロックの外。x = ${z}`); // ReferenceError: x is not defined
var
- varによって宣言された変数は「関数スコープ」をもつ(宣言された関数全体で有効になる)
巻き上げ(hoisting)
varを使って宣言した場合は、同じスコープの中であれば、たとえ宣言の前であっても有効になる。ただし巻き上げられるのは宣言だけであって、値の代入も巻き上げられるわけではない。したがって次のプログラムのように、宣言しただけではxの値はundefinedになる。
console.log(x);
var x = 3;
console.log(x);
varで宣言された変数のように、関数宣言もスコープの先頭に巻き上げられる。したがって、関数の宣言の前に呼び出すことができます。
f();
function f() {
console.log('関数fが呼び出された');
}
ただし、変数に代入された関数式は巻き上げられない。
f();
var f = function() {
console.log('関数fが呼び出された');
}
console.log(f);
f();
let命令とvar命令の比較
- let命令は同名の変数を許可しない
- var命令は重複を許容する(宣言を繰り返してもエラーにならない)
- let命令はブロックスコープを認識する(より細かく変数の有効範囲を管理できる)
- var命令の場合、ブロックの中で新しい変数を宣言したとしても関数全体がスコープになってしまう
- letを使って変数を宣言すると、宣言をするまでは存在しない(巻き上げが起きない)
script.js
let x = 3;
let x = 5; // Error
{
let x = 5;
}
console.log(x); // 3
var y = 3;
var y = 5;
{
var y = 5;
}
console.log(y); // 5
ES2015を利用できる環境では、できるだけlet命令を優先して利用することが推奨される
Strictモード
概要
- JavaScriptの落とし穴(暗黙的グローバル変数など)を検出して、エラーとして通知してくれるしくみ
- InternetExplorerではバージョン10以降でしか対応していない
-
'use strict';
は無害な文字列式で、非対応ブラウザーでは無視される - 利用するメリット
- 非Strictモードのコードよりも高速に動作する場合がある
- 将来のJavaScriptで変更される点を禁止することで、今後の移行が簡単になる
- JavaScriptの「べからず」を理解する手がかりになる
有効にする方法
-
スクリプトの先頭に
'use strict';
いう文を追加- 以降のスクリプト全体がStrictモードで解釈されるようになる
- 複数のスクリプトを連結した場合、以降のすべてのコードに影響を及ぼす
- 1つでも非Strictモードのコードが混在している場合には、正しく動作しない可能性がある
'use strict'; // スクリプトの先頭に追加 /* 任意のコード */
-
関数の本体先頭に「'use strict';」いう文を追加
- 関数内のスクリプトがStrictモードで解釈されるようにnaru
function hoge() { 'use strict'; //関数の本体先頭に追加 }
自分の書く関数についてはすべてstrictモードにしたいという場合、次のように全体のコードをひとつの関数としてラップしてしまう方法が使える。
script.js
(function() {
'use strict';
/*
* 自分のコードをここに書けば、すべてstrictモードで実行される。
* この外にあるスクリプトには影響しない
*/
})();
Strictモードまとめ
- 新規の開発では、できるだけStrictモードを有効にすることが推奨される
- 一般的には、関数の本体先頭に書く記法が望ましい(有効範囲を限定できる)
- 即時関数のイディオムを利用すれば、自然と自前のコード全体にStrictモードを適用できる