4 回答

TA贡献1883条经验 获得超3个赞
let
也可用于避免闭包问题。它绑定了新的价值而不是保留旧的参考,如下面的例子所示。
for(var i = 1; i < 6; i++) { document.getElementById('my-element' + i) .addEventListener('click', function() { alert(i) })}
上面的代码演示了一个典型的JavaScript闭包问题 对i
变量的引用存储在单击处理程序闭包中,而不是实际值i
。
每个单击处理程序都将引用同一个对象,因为只有一个计数器对象可以容纳6,因此每次单击时会得到6个。
一般的解决方法是将它包装在匿名函数中并i
作为参数传递。现在也可以通过使用let
替代var
方法来避免这些问题,如下面的代码所示。
演示(在Chrome和Firefox 50中测试)
'use strict';for(let i = 1; i < 6; i++) { document.getElementById('my-element' + i) .addEventListener('click', function() { alert(i) })}

TA贡献1802条经验 获得超4个赞
let
和之间有什么区别var
?
要了解其中的差异,请考虑以下代码:
// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here
function loop(arr) {
// i IS known here, but undefined
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( var i = 0; i < arr.length; i++ ) {
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( let j = 0; j < arr.length; j++ ) {
// i IS known here, and has a value
// j IS known here, and has a value
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
}
loop([1,2,3,4]);
for( var k = 0; k < arr.length; k++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
};
for( let l = 0; l < arr.length; l++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS known here, and has a value
};
loop([1,2,3,4]);
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
在这里,我们可以看到我们的变量j只在第一个for循环中被知道,而不是在之前和之后。然而,我们的变量i在整个函数中是已知的。
另外,请考虑块范围变量在声明之前是未知的,因为它们不会被提升。您也不允许在同一块中重新声明相同的块范围变量。这使得块范围变量比全局或功能范围变量更不容易出错,这些变量被提升并且在多个声明的情况下不会产生任何错误。
let
今天使用安全吗?
有些人会争辩说,将来我们只会使用let语句,而var语句将会过时。JavaScript大师凯尔辛普森写了一篇非常精细的文章,说明为什么他认为情况并非如此。
然而,今天绝对不是这样。事实上,我们实际上需要问自己,使用该let
陈述是否安全。这个问题的答案取决于您的环境:
如果您正在编写服务器端JavaScript代码(Node.js),则可以安全地使用该
let
语句。如果您正在编写客户端JavaScript代码并使用基于浏览器的转换器(如Traceur或babel-standalone),则可以安全地使用该
let
语句,但是您的代码在性能方面可能不是最优的。如果您正在编写客户端JavaScript代码并使用基于节点的转换器(如traceur shell脚本或Babel),则可以安全地使用该
let
语句。而且因为您的浏览器只会知道转换后的代码,所以应该限制性能缺陷。如果您正在编写客户端JavaScript代码而不使用转换器,则需要考虑浏览器支持。
仍然有一些浏览器根本不支持
let
:
如何跟踪浏览器支持
有关let
在阅读本答案时哪些浏览器支持该语句的最新概述,请参阅此Can I Use
页面。
(*)全局和功能范围的变量可以在声明之前初始化和使用,因为JavaScript变量是悬挂的。这意味着声明始终位于范围的顶部。
(**)未提升块范围变量
添加回答
举报