Join MDN and developers like you at Mozilla's View Source conference, 12-14 September in Berlin, Germany. Learn more at https://viewsourceconf.org

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

構文

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

引数

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

説明

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

let とブロックスコープ

ブロックの中で変数を定義するには let キーワードを使います。

if (x > y) {
  let gamma = 12.7 + y;
  i = gamma * x;
}

let を使うことで、内部関数を扱うコードがきれいになる時もあります。

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

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

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

上の例は意図した通りに動き、5つの(無名の)内部関数のインスタンスは5通りに実現された変数 j を参照します。内部関数にある letvar に取り替えたり、単に変数 j を取り去ったりすると、意図通りには動かなくことに注意してください。

スコーピングのルール

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
}

プログラムまたは関数のトップレベルでは、 let はまさに var と同じ動作をします。例えば次のようにです。

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

このコードでは "global" が二回出力されます。

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

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

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

ECMAScript 6 では 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;
}

for ループの中でのlet でスコープされた変数

let キーワードを使って、 for ループのスコープに変数を局所束縛できます。ループの先頭に置いた var キーワードではそのループを含んでいる関数全体に変数が見えてしまいますが、 let キーワードは違います。

var i=0;
for ( let i=i ; i < 10 ; i++ ) {
  console.log(i);
}

スコーピングのルール

for (let expr1; expr2; expr3) statement

この例では expr2expr3statementlet expr1 で宣言されているブロックローカル変数を含んだ暗黙のブロックに囲まれています。これは上の最初のループで示されています。

let vs var

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

var a = 5;
var b = 10;

if (a === 5) {
  let a = 4; // スコープは if ブロックの内側
  var b = 1; // スコープは関数の内側

  console.log(a);  // 4
  console.log(b);  // 1
} 

console.log(a); // 5
console.log(b); // 1

ループの中の let

グローバル変数の代わりに、 let キーワードで変数をループのスコープに局所的に束縛できます。

for (let i = 0; i<10; i++) {
  console.log(i); // 0, 1, 2, 3, 4 ... 9
}

console.log(i); // i は定義されていない

標準的でない 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 を囲んで作られる暗黙のブロックがあります。

Specifications

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Let and Const Declarations' in that specification.
Standard Initial definition. Does not specify let expressions or let blocks.
ECMAScript 2016 Draft (7th Edition, ECMA-262)
The definition of 'Let and Const Declarations' in that specification.
ドラフト  

ブラウザー互換性

Feature Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
Basic support 41.0 (有) 44 (44) 11 17 ?
Temporal dead zone ? (有) 35 (35) ? ? ?
let expression 未サポート 未サポート 未サポート 未サポート 未サポート 未サポート
let block 未サポート 未サポート 未サポート 未サポート 未サポート 未サポート
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support ? 41.0 44.0 (44) ? ? ?
Temporal dead zone ? ? 35.0 (35) ? ? ?
let expression 未サポート 未サポート 未サポート 未サポート 未サポート 未サポート
let block 未サポート 未サポート 未サポート 未サポート 未サポート 未サポート

Firefox 特有の注意

  • SpiderMonkey 44 (Firefox 44 / Thunderbird 44 / SeaMonkey 2.41) 以前では、 let

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

タグ: 
 このページの貢献者: Motchy, cohei, teoli, ethertank, Susisu, Wladimir_Palant, Potappo
 最終更新者: Motchy,