Javascript闭包:通过一个示例理解let和var之间的差异
虽然我知道let允许您声明限制在块范围内的变量,但在将let与var用于javascript闭包时,我遇到了一个奇怪的区别。以下是我的例子: 使用letJavascript闭包:通过一个示例理解let和var之间的差异,javascript,jquery,Javascript,Jquery,虽然我知道let允许您声明限制在块范围内的变量,但在将let与var用于javascript闭包时,我遇到了一个奇怪的区别。以下是我的例子: 使用let function buildFunction(){ var-arr=[]; 对于(变量i=0;i
function buildFunction(){
var-arr=[];
对于(变量i=0;i<3;i++){
let j=i;//使用let分配j
arr.push(
函数(){
控制台日志(j);
}
)
}
返回arr;
}
var fs=buildFunction();
fs[0]();
fs[1]();
fs[2]()代码>var
作用域到函数<代码>让
作用于一个代码块
在您的示例中,当您使用var时,j
的作用域是函数buildFunction()
。这意味着您在每个函数中使用“相同的”j
。当for循环运行j设置为0、1、2时。然后,当您运行控制台时,会记录您引用设置为2的j的情况,因此会得到2
当您使用let
时,您将j
范围限定到for循环的迭代。这意味着每个迭代都有一个“不同的”j
,控制台日志会打印您希望它们打印的内容
如果您使用的是ES5并且需要使用var,则可以复制let效应(让它打印0 1 2
),方法是将原始匿名函数包装为一个自执行函数,并将j
作为参数传入。这将为自执行函数中的j
创建一个新范围,其值为当前迭代中的j值
function buildFunction(){
var-arr=[];
对于(变量i=0;i<3;i++){
var j=i;//使用var分配j
arr.push(
//自动执行功能
(函数(j){//j此处的作用域为自执行函数,在循环中调用时,其值为j。此处对j的任何更改都不会影响此函数外部的j作用域,而对此函数外部的j的任何更改都不会影响此函数内部的j作用域。
//原函数
返回函数(){
控制台日志(j);
}
})(j) //在此迭代中使用值j调用
)
}
返回arr;
}
var fs=buildFunction();
fs[0]();
fs[1]();
fs[2]()代码>@oen44:不,这不是重复的。请仔细阅读这个问题,我认为它回答了“如果我在一个块中使用var,它不应该像let一样工作吗?”非常好。那么,第二个问题(否)的答案就变得无关紧要了。