JavaScript let
1. JavaScript let の概要
let キーワードは、ES6 (2015) で導入されました。
letで宣言されたバリアブルはブロックスコープを持ちます。letで宣言されたバリアブルは、使用する前にデクレア(宣言)する必要があります。letで宣言されたバリアブルは、同じスコープ内で再宣言することができません。
2. ブロックスコープ (Block Scope)
ES6 (2015) より前、JavaScriptにはブロックスコープが存在しませんでした。
当時のJavaScriptには、グローバルスコープと関数スコープしかありませんでした。
ES6で導入された let と const という2つの新しいキーワードにより、JavaScriptにブロックスコープがもたらされました。
コード例{ } ブロック内で宣言されたバリアブルは、ブロックの外からアクセスすることはできません。
{
let x = 2;
}
// ここで x は使用できません3. 関数スコープ (Function Scope)
ファンクションの内部で宣言されたバリアブルは、var、let、const のいずれであっても関数スコープを持ちます。
コード例
function myfunction() {
var x = 1; // 関数スコープ
let y = 2; // 関数スコープ
const z = 3; // 関数スコープ
}
// ここで x は使用できません
// ここで y は使用できません
// ここで z は使用できません4. グローバルスコープ (Global Scope)
var キーワードで宣言されたバリアブルは、常にグローバルスコープ、あるいは(関数内の場合は)関数スコープを持ちます。var で宣言されたバリアブルは、ブロックスコープを持つことができません。
コード例{ } ブロック内で var を使用して宣言されたバリアブルは、ブロックの外からアクセス可能です。
{
var x = 2;
}
// ここで x を使用できます5. 再宣言の禁止 (Cannot be Redeclared)
let で定義されたバリアブルは再宣言できません。
これにより、誤って既存のバリアブルを上書きしてしまうリスクを回避できます。
let では、以下のような記述は不可能です。
let x = "ジョン・ドウ";
let x = 0; // 構文エラーになります対して、var で定義されたバリアブルは何度でも再宣言が可能です。
var x = "ジョン・ドウ";
var x = 0; // 許容されます6. 変数の再宣言による影響 (Redeclaring Variables)
var キーワードを使用した再宣言は、しばしば問題を引き起こします。
ブロック内でバリアブルを再宣言すると、ブロックの外にある同名のバリアブルまで上書きされてしまいます。
コード例(var の場合)
var x = 10;
// ここで x は 10
{
var x = 2;
// ここで x は 2
}
// ブロックの外でも x は 2 になってしまうlet キーワードを使用すれば、この問題を解決できます。
ブロック内でバリアブルを再宣言しても、ブロック外のバリアブルには影響を与えません。
コード例(let の場合)
let x = 10;
// ここで x は 10
{
let x = 2;
// ここで x は 2
}
// ブロックの外では x は依然として 107. var, let, const の違い
| 特徴 | var | let | const |
|---|---|---|---|
| ブロックスコープ | No | Yes | Yes |
| 再宣言 | Yes | No | No |
| 再代入(アサイン) | Yes | Yes | No |
| ホイスティング | Yes | Yes (※) | Yes (※) |
| this へのバインド | Yes | No | No |
let と const もホイスティングされますが、初期化されないため、宣言前にアクセスするとエラーになります。
7.1 何が優れているのか?
letとconstはブロックスコープを持ちます。letとconstは再宣言ができません。letとconstは使用前にデクレアする必要があります。letとconstはthisにバインドされません。letとconstは(実質的に)ホイスティングされません。
7.2 何が問題か?
varは宣言しなくても使えてしまう場合があります(古い挙動)。varはホイスティングされます。varはthisにバインドされます。
8. ブラウザのサポート状況
let および const キーワードは、Internet Explorer 11 以前ではサポートされていません。
以下の表は、完全なサポートを開始した最初のブラウザバージョンを示しています。
| Chrome 49 | Edge 12 | Firefox 36 | Safari 11 | Opera 36 |
|---|---|---|---|---|
| 2016年3月 | 2015年7月 | 2015年1月 | 2017年9月 | 2016年3月 |
9. スコープ別の再宣言ルール
var を使った再宣言は、プログラムのどこでも許可されます。
コード例
var x = 2;
// 現在 x は 2
var x = 3;
// 現在 x は 3しかし、let を使用する場合、同じブロック内での再宣言は許可されません。
コード例
var x = 2; // 許容される
let x = 3; // 許可されない(エラー)
{
let x = 2; // 許容される
let x = 3; // 許可されない(エラー)
}
{
let x = 2; // 許容される
var x = 3; // 許可されない(エラー)
}異なるブロック内であれば、let を使用して同名のバリアブルを宣言することは可能です。
コード例
let x = 2; // 許容される
{
let x = 3; // 許容される
}
{
let x = 4; // 許容される
}10. let とホイスティング (Let Hoisting)
var で定義されたバリアブルは、スコープの先頭にホイスティング(巻き上げ)され、いつでも初期化可能です。 つまり、デクレアする前にそのバリアブルを使用することができます。
コード例
以下のコードは正常に動作します。
carName = "ボルボ";
var carName;※ホイスティングについて詳しく知りたい場合は、「JavaScript Hoisting」の章を参照してください。
let で定義されたバリアブルもブロックの先頭にホイスティングされますが、初期化はされません。
そのため、let バリアブルを宣言前に使用しようとすると、ReferenceError(参照エラー)が発生します。
コード例
carName = "サーブ";
let carName = "ボルボ"; // ReferenceError が発生します