翻译正在进行中。

该新特性属于 ECMAScript 2015(ES6)规范,在使用时请注意浏览器兼容性。

let 关键字申明了一个块级域的本地变量,在申明变量的时候可同时赋值。

let 关键字在火狐下默认还是无效的,除非把脚本标签特殊申明: <script type="application/javascript;version=1.7"> (必须是1.7以上). XUL 的脚本不需要这样注明,因为默认已经支持。不过这种写法是实验性的,以后可能会废除。

语法

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

参数

var1, var2, …, varN
一些合法的变量名称。
value1, value2, …, valueN
给变量的值,可以是任何表达式。

描述

let 允许把变量的作用域限制在块级域中。与 var 不同处是:var 申明变量要么是全局的,要么是函数级的,而无法是块级的。

在块级域中用 let

用 let 在一个代码块中定义变量.

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

也可以将let定义的变量作为伪名称空间的别名. (See Security best practices in extensions.)

let Cc = Components.classes, Ci = Components.interfaces;

在用到内部函数的时候,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个li,点击不同的li能够打印出当前li的序号。如果不用let,而改用var的话,将总是打印出 Item 5 is Clicked,因为j是函数级变量,5个内部函数都指向了同一个j,而j最后一次赋值是5。用了let后,j 变成块级域(也就是花括号中的块,每进入一次花括号就生成了一个块级域)

Scoping rules

Variables declared by let have as their scope the block in which they are defined, as well as in any contained sub-blocks . In this way, let works very much like var. The main difference is that the scope of a var variable is the entire enclosing function:

function varTest() {
  var x = 31;
  if (true) {
    var x = 71;  // same variable!
    console.log(x);  // 71
  }
  console.log(x);  // 71
}

function letTest() {
  let x = 31;
  if (true) {
    let x = 71;  // different variable
    console.log(x);  // 71
  }
  console.log(x);  // 31
}

At the top level of programs and functions, let behaves exactly like var does. For example:

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

The output displayed by this code will display "global" twice.

Temporal dead zone and errors with let

Redeclaration of the same variable in the same block scope raises a TypeError.

if (x) {
  let foo;
  let foo; // TypeError thrown.
}

However, function bodies do not have this limitation!

function do_something() {
  let foo;
  let foo; // This works fine.
}

In ECMAScript 6, let does not hoist the variable to the top of the block. If you reference a variable in a block before the let declaration for that variable is encountered, this results in a ReferenceError, because the variable is in a "temporal dead zone" from the start of the block until the declaration is processed.

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

You may encounter errors in switch statements because there is only one underlying block.

switch (x) {
  case 0:
    let foo;
    break;
    
  case 1:
    let foo; // TypeError for redeclaration.
    break;
}

let-scoped variables in for loops

You can use the let keyword to bind variables locally in the scope of for loops. This is different from the var keyword in the head of a for loop, which makes the variables visible in the whole function containing the loop.

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

Scoping rules

for (let expr1; expr2; expr3) statement

In this example, expr2, expr3, and statement are enclosed in an implicit block that contains the block local variables declared by let expr1. This is demonstrated in the first loop above.

Examples

let vs var

When used inside a block, let limits the variable's scope to that block. Note the difference between var whose scope is inside the function where it is declared

var a = 5;
var b = 10;

if (a === 5) {
  let a = 4; // The scope is inside the if-block
  var b = 1; // The scope is inside the function

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

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

let in loops

You can use the let keyword to bind variables locally in the scope of loops instead of using a global variable (defined using var) for that.

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

console.log(i); // i is not defined

Non-standard let extensions

The let block and let expression syntax is non-standard and will be removed in the future. Do not use them! See bug 1023609 and bug 1167029 for more details.

let blocks

The let block provides a way to associate values with variables within the scope of a block, without affecting the values of like-named variables outside the block.

Syntax

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

Description

The let block provides local scoping for variables. It works by binding zero or more variables in the lexical scope of a single block of code; otherwise, it is exactly the same as a block statement. Note in particular that the scope of a variable declared inside a let block using var is still the same as if it had been declared outside the let block; such variables still have function scoping. When using the let block syntax, the parentheses following let are required. Failure to include them will result in a syntax error.

Example

var x = 5;
var y = 0;

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

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

The rules for the code block are the same as for any other code block in JavaScript. It may have its own local variables established using the let declarations.

Scoping rules

The scope of variables defined using let is the let block itself, as well as any inner blocks contained inside it, unless those blocks define variables by the same names.

let expressions

let expression support has been dropped in Gecko 41 (bug 1023609).

The let expression lets you establish variables scoped only to a single expression.

Syntax

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

Example

You can use let to establish variables that are scoped only to a single expression:

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

Scoping rules

Given a let expression:

let (decls) expr

There is an implicit block created around expr.

Specifications

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
Let and Const Declarations
Standard Initial definition. Does not specify let expressions or let statements.

Browser compatibility

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support

41.0

2.0 (1.8.1) [1] 11 17 ?
Temporal dead zone ? 35 (35) [1] ? ? ?
let expression 未实现 2.0 (1.8.1)-40 (40) [1] 未实现 未实现 未实现
let block 未实现 2.0 (1.8.1) [1] 未实现 未实现 未实现
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support ?

41.0

1.0 (1.8.1) [1] ? ? ?
Temporal dead zone ? ? 35.0 (35) [1] ? ? ?
let expression 未实现 未实现 1.0 (1.8.1)-40.0 (40)[1] 未实现 未实现 未实现
let block 未实现 未实现 1.0 (1.8.1) [1] 未实现 未实现 未实现

Firefox-specific notes

  • [1]: Only available to code blocks in HTML wrapped in a <script type="application/javascript;version=1.7"> block (or higher version). Beware, however, that as this is a non-standard feature, this will most likely break support for other browsers. XUL script tags have access to these features without needing this special block. See bug 932517 and bug 932513.
  • ES6 compliance for let in SpIderMonkey is tracked in bug 950547 and non-standard extensions are going to be removed in the future bug 1023609.

See also

文档标签和贡献者

向此页面作出贡献: ouonet, ziyunfei, WangZishi, Junjie_Wei, teoli, SphinxKnight, Nightire, ted423
最后编辑者: ouonet,
隐藏侧边栏