javascript 中如何将值传递给回调
how values are passed to callbacks in javascript
我想了解 javascript 引擎如何以及何时将值传递给回调函数,我尝试调试并在线查找但找不到确切答案,请考虑以下示例:
for(var i = 0; i < 4; i++) {
console.log("outside callback " + i + " ");
setTimeout(function test(){
console.log("inside callback " + i + " ");
},100);
}
这将打印以下输出
outside callback 0
outside callback 1
outside callback 2
outside callback 3
inside callback 4
inside callback 4
inside callback 4
inside callback 4
如果我只是使用 let 关键字更改 i 变量的声明如下:
for(let i = 0; i < 4; i++) {
console.log("outside callback " + i + " ");
setTimeout(function test(){
console.log("inside callback " + i + " ");
},100);
}
结果如下:
outside callback 0
outside callback 1
outside callback 2
outside callback 3
inside callback 0
inside callback 1
inside callback 2
inside callback 3
在 Chrome 中调试时,它在第一个示例中将 i 显示为测试函数的闭包范围,在第二个示例中显示为块范围。
其实是因为varaibles的作用域是用let和var声明的,而不仅仅是javascript的闭包属性。
这与有关 JavaScript closure inside loops – simple practical example 的常见问题有关,该问题详细说明了为什么在循环中创建的回调函数内部,使用 var
声明的变量具有循环时达到的值结束:虽然在设置回调时它们可能持有不同的值,但在执行回调时,异步,一段时间后,循环早已完成并将变量留在闭包中循环完成时它们所持有的值。
从 ECMAScript 版本 6 开始,使用 let
声明的变量是块作用域的,不能在定义它们的代码块之外访问。 另外 for
循环控制语句中定义的变量得到特殊处理。
- 它们的作用域是
for
循环体,而不是包含 for
循环的代码块。
为循环的每次迭代创建 let
变量的新绑定。这意味着每次迭代都可以有自己的一组变量值,保存在为迭代创建的词法环境记录中,可以在闭包中使用并由循环中定义的回调函数访问。
每个词法环境记录中循环计数器的值旨在使多个环境记录的使用在很大程度上透明:
for( part1; part2; part3) {
// loop body code
}
- 在第一次迭代中,
let
在 for
语句中定义的变量具有它们在执行 part1
和 part2
. 后的值
- 在随后的迭代中,它们的值是通过将当前迭代的环境记录中的值初始化为上一次迭代结束时的值来确定的,然后执行
part3
和 part2
在上面的 for
语句中。
- 在
for
循环体内声明的回调函数访问在调用迭代的 结束 处保存的 let
定义变量的值back 已设置,排除 计算 for
语句的 part3
的副作用。
我想了解 javascript 引擎如何以及何时将值传递给回调函数,我尝试调试并在线查找但找不到确切答案,请考虑以下示例:
for(var i = 0; i < 4; i++) {
console.log("outside callback " + i + " ");
setTimeout(function test(){
console.log("inside callback " + i + " ");
},100);
}
这将打印以下输出
outside callback 0
outside callback 1
outside callback 2
outside callback 3
inside callback 4
inside callback 4
inside callback 4
inside callback 4
如果我只是使用 let 关键字更改 i 变量的声明如下:
for(let i = 0; i < 4; i++) {
console.log("outside callback " + i + " ");
setTimeout(function test(){
console.log("inside callback " + i + " ");
},100);
}
结果如下:
outside callback 0
outside callback 1
outside callback 2
outside callback 3
inside callback 0
inside callback 1
inside callback 2
inside callback 3
在 Chrome 中调试时,它在第一个示例中将 i 显示为测试函数的闭包范围,在第二个示例中显示为块范围。
其实是因为varaibles的作用域是用let和var声明的,而不仅仅是javascript的闭包属性。
这与有关 JavaScript closure inside loops – simple practical example 的常见问题有关,该问题详细说明了为什么在循环中创建的回调函数内部,使用 var
声明的变量具有循环时达到的值结束:虽然在设置回调时它们可能持有不同的值,但在执行回调时,异步,一段时间后,循环早已完成并将变量留在闭包中循环完成时它们所持有的值。
从 ECMAScript 版本 6 开始,使用 let
声明的变量是块作用域的,不能在定义它们的代码块之外访问。 另外 for
循环控制语句中定义的变量得到特殊处理。
- 它们的作用域是
for
循环体,而不是包含for
循环的代码块。 为循环的每次迭代创建
let
变量的新绑定。这意味着每次迭代都可以有自己的一组变量值,保存在为迭代创建的词法环境记录中,可以在闭包中使用并由循环中定义的回调函数访问。每个词法环境记录中循环计数器的值旨在使多个环境记录的使用在很大程度上透明:
for( part1; part2; part3) { // loop body code }
- 在第一次迭代中,
let
在for
语句中定义的变量具有它们在执行part1
和part2
. 后的值
- 在随后的迭代中,它们的值是通过将当前迭代的环境记录中的值初始化为上一次迭代结束时的值来确定的,然后执行
part3
和part2
在上面的for
语句中。 - 在
for
循环体内声明的回调函数访问在调用迭代的 结束 处保存的let
定义变量的值back 已设置,排除 计算for
语句的part3
的副作用。
- 在第一次迭代中,