这篇文章需要文法复核。如何帮忙。
这篇翻译不完整。请帮忙从英语翻译这篇文章。
let
声明了一个块级域的局部变量,并且可以给它一个初始化值。
语法
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
能够让代码更简洁,比如:
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 变成块级域(也就是花括号中的块,每进入一次花括号就生成了一个块级域),所以 5 个内部函数指向了不同的 j 。
作用域规则
用 let 定义的变量的作用域是定义它们的块内,以及包含在这个块中的子块 ,这一点有点象var,只是var 定义的变量的作用域是定义它们的函数内 :
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 }
在程序或者函数的顶层,let 的表现就象 var 一样:
var x = 'global'; let y = 'global'; console.log(this.x); console.log(this.y);
上面这段代码的运行后会显示两次"global"。
注:在 Safari[版本 9.1.1 (9537.86.6.17)]与 chrome[ 版本50.0.2661.102 (64-bit)]中 y 将是 undefined
let 的暂存死区与错误
在同一个函数或同一个作用域中用let重复定义一个变量将引起 TypeError
.
if (x) { let foo; let foo; // TypeError thrown. }
在 ECMAScript 2015中, let
将会提升这个变量到语句块的顶部。然而,在这个语句块中,在变量声明之前引用这个变量会导致一个 ReferenceError的结果
, 因为let变量 在"暂存死区" (从块的开始到声明这段).
function do_something() { console.log(foo); // ReferenceError let foo = 2; }
在 switch
声明中你可能会遇到这样的错误,因为一个switch只有一个作用块.
switch (x) { case 0: let foo; break; case 1: let foo; // TypeError for redeclaration. break; }
循环定义中的let作用域
循环体中是可以引用在for申明时用let定义的变量,尽管let不是出现在大括号之间.
var i=0; for ( let i=i ; i < 10 ; i++ ) { console.log(i); }
注:以上 let 申明的 i 将会变成 undefined;chrome 版本50.0.2661.102 (64-bit);推荐以下写法:
var i=0; for ( let l = i ; l < 10 ; l++ ) { console.log(l); }
域作用规则
for (let expr1; expr2; expr3) statement
在这个例子中,expr2, expr3, 和 statement 都是包含中在一个隐含域块中,其中也包含了 expr1.
例子
let
对比 var
let的作用域是块,而var的作用域是函数
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
在循环中
可以用 let 来代替 var ,在 for 定义块中使用块级变量.
for (let i = 0; i<10; i++) { console.log(i); // 0, 1, 2, 3, 4 ... 9 } console.log(i); // i is not defined
非标准的 let 扩展
let块(
let
block)
let blocks 在 Gecko 44 中已经废除( bug 1167029) 。
let块
提供了一种在块的范围内获取变量的值,而不会影响块外面名字相同的变量的值的方法。
语法
let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) block;
描述
let 语句块为变量提供了局部作用域。它的作用是在单一代码块的词法范围内绑定零个或多个变量; 此外与普通语句块没有任何区别。需要特别注意的是, 在 let
语句块内使用 var 声明的变量,它的作用域与在 let 语句块之外声明没有区别;这样的变量仍然具有函数作用域。在使用 let
语句块时,必须使用花括号,否则会导致语法错误。
例子
var x = 5; var y = 0; let (x = x+10, y = 12) { console.log(x+y); // 27 } console.log(x + y); // 5
let 代码块的规则与 JavaScript 中其他类型的代码块相同。允许在块内通过 let 关键字声明局部变量。
作用域规则
使用 let
语句块绑定的变量,其作用域是 let
语句块本身,与任何其内部语句块的作用域一样,除非在这些内部语句块内又定义了同名的变量。
let
表达式( let expression)
let
expression 在 Gecko 41 已经废除(bug 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 的语句块。
规范
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) Let and Const Declarations |
Standard | Initial definition. Does not specify let expressions or let blocks. |
ECMAScript 2017 Draft (ECMA-262) Let and Const Declarations |
Draft |
浏览器兼容性
Feature | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic support | 41.0 | (Yes) | 44 (44) | 11 | 17 | ? |
Temporal dead zone | ? | (Yes) | 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-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 932517. - 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.