この翻訳は不完全です。英語から この記事を翻訳 してください。

let 文はブロックスコープの局所変数を宣言します。任意で値を代入して初期化できます。

構文

let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];

引数

var1, var2, …, varN
変数の名前。任意の有効な識別子を指定できます。
value1, value2, …, valueN
変数の初期値。任意の有効な式を指定できます。

説明

let を使用することで、変数のスコープをそれが使用されたブロック、文または式に限定することができます。これは var キーワードとは異なり、グローバル変数を定義したり、ブロックスコープに留まらない関数全体でのローカル変数を定義したりしません。

An explanation of why the name "let" was chosen can be found here.

スコーピングのルール

let で定義された変数では、自身が定義されたブロックがスコープになります。そのブロックに含まれている全てのサブブロックでも同様です。この点において let のふるまいは var にとてもよく似ています。主に違うのは、 var で定義された変数のスコープはそれを含んでいる関数全体になるということです。次のコードはその例です。

function varTest() {
  var x = 31;
  if (true) {
    var x = 71;  // 同じ変数です!
    console.log(x);  // 71
  }
  console.log(x);  // 71
}

function letTest() {
  let x = 31;
  if (true) {
    let x = 71;  // 異なる変数
    console.log(x);  // 71
  }
  console.log(x);  // 31
}

var とは異なり、プログラムのトップレベルと関数で、グローバルオブジェクト上にプロパティを生成しません。たとえば:

var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined

内部関数でのクリーンなコード

let は、しばしば内部関数で使用されるとコードをクリーンにします。

var list = document.getElementById("list");

for (let i = 1; i <= 5; i++) {
  let item = document.createElement("li");
  item.appendChild(document.createTextNode("Item " + i));

  item.onclick = function (ev) {
    console.log("Item " + i + " is clicked.");
  };
  list.appendChild(item);
}

上述の例は、5 つの(匿名)内部関数のインスタンスが 5 つの異なる変数 i のインスタンスを参照するため、意図したとおりに動作します。letvar で置き換えた場合、すべての内部関数は i の同じ最終値  6 を 返すため、意図したとおりに動作しないことに注意してください。また、我々は、各ループのスコープに新しい要素を生成するコードを移動することによって、ループ周りのスコープをクリーンに保つことができます。

 

プライベートインターフェースのエミュレート

constructor で処理することで、クロージャを使用することなくプライベートインターフェースを生成するために let ステートメントを使用できます:

var SomeConstructor;

{
    let privateScope = {};

    SomeConstructor = function SomeConstructor () {
        this.someProperty = "foo";
        privateScope.hiddenProperty = "bar";
    }

    SomeConstructor.prototype.showPublic = function () {
        console.log(this.someProperty); // foo
    }

    SomeConstructor.prototype.showPrivate = function () {
        console.log(privateScope.hiddenProperty); // bar
    }

}

var myInstance = new SomeConstructor();

myInstance.showPublic();
myInstance.showPrivate();

console.log(privateScope.hiddenProperty); // error

Temporal dead zone と let に関するエラー

同じ関数かブロックスコープで同じ変数を再宣言すると SyntaxError が発生します。

if (x) {
  let foo;
  let foo; // SyntaxError が投げられます。
}

ECMAScript 2015 では let は変数をブロックの先頭へ引き上げます。しかし、その変数を宣言より前で参照することは ReferenceError を引き起こします。ブロックの始めから変数宣言が実行されるまで、変数は "temporal dead zone" の中にいるのです。

function do_something() {
  console.log(foo); // ReferenceError
  let foo = 2;
}

switch 文には1つのブロックしかないため、エラーを発生させてしまうかもしれません。

switch (x) {
  case 0:
    let foo;
    break;
    
  case 1:
    let foo; // 再宣言によって TypeError
    break;
}

関数に渡されるパラメータと同じ変数名で let を使用すると、for ループ内で undefined となります。

function go(n){
  for (let n of n.a) {
    console.log(n);
  }
}

go({a:[1,2,3]});

そのほかの例

ブロックの中で使うなら、 let の変数のスコープはそのブロックの中に制限されます。スコープが自身の宣言された関数全体になる var との違いに注意してください。

var a = 1;
var b = 2;

if (a === 1) {
  var a = 11; // スコープはグローバル
  let b = 22; // スコープは if ブロック内

  console.log(a);  // 11
  console.log(b);  // 22
} 

console.log(a); // 11
console.log(b); // 2

標準的でない let 拡張

let ブロック

let ブロックは Gecko 44 からサポートされなくなっています (バグ 1167029) 。

let ブロックは、ブロックの外にある似た名前の変数の値に影響を与えずに、ブロックのスコープの中にある変数と値を関連づけるやり方を提供します。

構文

let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) block;

説明

let ブロックは変数に局所的なスコープをつけることを可能にします。コードブロックのレキシカルスコープに0個以上の変数を束縛するという動作をします。そのほかの点では、これはブロック文と全く同じです。let ブロックの中で var を使って宣言された変数のスコープは、依然として let ブロックの外で宣言されたのと同じだということに特に注意してください。そのような変数はやはり関数スコープを持ちます。 let ブロックを使うとき、 let に続く括弧は必須です。括弧を忘れると構文エラーが発生します。

var x = 5;
var y = 0;

let (x = x+10, y = 12) {
  console.log(x+y); // 27
}

console.log(x + y); // 5

このコードブロックについての規則は JavaScript のほかのコードブロックと同じです。 let での変数宣言を使って、このブロック内のローカル変数を作ることができます。

スコープのルール

let を使って定義された変数のスコープは let ブロックそれ自体と、そこに含まれるほかのサブブロックですが、サブブロックで同名の変数が定義されているときを除きます。

let

let 式は Gecko 41 からサポートされなくなっています (バグ 1023609) 。

letは単一の式のみにスコープされた変数を作ることを可能にします。

構文

let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) expression;

単一の式のみにスコープされた変数を作るために、 let が使えます。

var a = 5;
let(a = 6) console.log(a); // 6
console.log(a); // 5

スコープの規則

let 式があるとして:

let (decls) expr

expr を囲んで作られる暗黙のブロックがあります。

仕様

仕様 ステータス コメント
ECMAScript 2015 (6th Edition, ECMA-262)
Let and Const Declarations の定義
標準 初期定義。let 式や let ブロックは定義されていない。
ECMAScript Latest Draft (ECMA-262)
Let and Const Declarations の定義
ドラフト  

ブラウザー互換性

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeEdge MobileAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
基本対応Chrome 完全対応 49
完全対応 49
未対応 48 — 49
補足 無効
補足 Support outside of strict mode.
無効 From version 48 until version 49 (exclusive): this feature is behind the Enable Experimental JavaScript Features preference. To change preferences in Chrome, visit chrome://flags.
未対応 41 — 49
補足
補足 Strict mode is required.
Edge 完全対応 12Firefox 完全対応 44
補足
完全対応 44
補足
補足 Prior to Firefox 44, let is only available to code blocks in HTML wrapped in a <script type="application/javascript;version=1.7"> block (or higher version) and has different semantics (e.g. no temporal dead zone).
補足 Prior to Firefox 46, a TypeError is thrown on redeclaration instead of a SyntaxError.
補足 Firefox 54 adds support of let in workers.
IE 完全対応 11Opera 完全対応 17Safari 完全対応 10WebView Android 完全対応 49
完全対応 49
未対応 41 — 49
補足
補足 Strict mode is required.
Chrome Android 完全対応 49
完全対応 49
未対応 48 — 49
補足 無効
補足 Support outside of strict mode.
無効 From version 48 until version 49 (exclusive): this feature is behind the Enable Experimental JavaScript Features preference. To change preferences in Chrome, visit chrome://flags.
未対応 41 — 49
補足
補足 Strict mode is required.
Edge Mobile 完全対応 12Firefox Android 完全対応 44
補足
完全対応 44
補足
補足 Prior to Firefox 44, let is only available to code blocks in HTML wrapped in a <script type="application/javascript;version=1.7"> block (or higher version) and has different semantics (e.g. no temporal dead zone).
補足 Prior to Firefox 46, a TypeError is thrown on redeclaration instead of a SyntaxError.
補足 Firefox 54 adds support of let in workers.
Opera Android 完全対応 17Safari iOS 完全対応 10Samsung Internet Android 完全対応 4.0nodejs 完全対応 6.0.0

凡例

完全対応  
完全対応
実装ノートを参照してください。
実装ノートを参照してください。
ユーザーが明示的にこの機能を有効にしなければなりません。
ユーザーが明示的にこの機能を有効にしなければなりません。

 

Firefox 特有の注意

  • SpiderMonkey 46 (Firefox 46 / Thunderbird 46 / SeaMonkey 2.43) 以下では、再宣言すると SyntaxError の代わりに TypeError がスローされます バグ 1275240)。
  • SpiderMonkey 44 (Firefox 44 / Thunderbird 44 / SeaMonkey 2.41) 以下では、let<script type="application/javascript;version=1.7"> ブロック(またはより高いバージョン)にラップされた HTML のコードブロックでのみ使用可能であり、異なるセマンティックを持っていました。
  • Worker コード内でのサポートは、dom.workers.latestJSVersion フラグで隠されています (バグ 487070)。自由に let を使用できるバージョンから、このフラグは削除されます (バグ 1219523)。
  • SpIderMonkey での let の ES6 コンプライアンスは、バグ 950547 でトラックされています。

関連項目

ドキュメントのタグと貢献者

最終更新者: isdh,