问题描述
我正在浏览高级JavaScript文本,遇到了这些代码,我想作者试图演示闭包,但没有解释代码。我一直盯着这些代码几个小时,仍然不能弄清楚为什么他们会产生不同的输出。
c> c 在第二个代码块中, for 循环将再次运行到完成,但每次通过 for 一个新的函数闭包,它为每个定时器回调分别捕获 i 的值,因此它将显示 i $ c $ setTimeout()回调,因为它已为每个计时器分别保存。
你的第二个代码更像这样:
function myTimer(index){
setTimeout(function(){
console.log('i value in closure is'+ index);
},index);
}
for(var i = 0; i myTimer
}
第二个代码块和这个扩展代码之间的唯一区别是,第二代码块使用一个无关的IIFE而不是这里所示的 myTimer()函数,但执行是相同的。在中为循环使用此函数创建一个Javascript函数闭包,保存 i 的值, setTimeout()稍后调用其回调, i 的唯一值可用于回调,
$ b(function( i){
这里的一些异步操作使用i
})(i);
称为 立即调用的函数表达式 (缩写为IIFE),并且是在Javascript中创建闭包的快速方法。
有关此主题的更多信息,请参阅此先前的答案:
I was going through an Advanced JavaScript text and came across these codes, I think the writer was trying to demonstrate closures but didn't explain the codes. I've been staring at these sets of codes for hours and still can't figure out why they will produce different output.
for (var i = 0; i <= 2000; i += 1000) { setTimeout(function () { console.log('i value in closure is ' + i); }, i); } //Output // i value in closure is 2000 // i value in closure is 2000 // i value in closure is 2000`and
for (var i = 0; i <= 2000; i += 1000) { (function (i) { setTimeout(function () { console.log('i value in closure is ' + i); }, i); })(i); } //Output // i value in closure is 0 // i value in closure is 1000 // i value in closure is 2000`解决方案In the first code block, the for loop will run to completion. Each time through the loop will schedule a setTimeout() call for some time in the future. But, when that setTimeout() actually fires, the value of i will be the value at the END of the for loop for all the setTimeout() calls.
In the second code block, the for loop will again run to completion, but each time through the for loop it creates a new function closure that "captures" the value if i separately for each timer callback and thus it will display the desired value of i inside the setTimeout() callback because it has been saved separately for each timer.
You can think of your second code more like this:
function myTimer(index) { setTimeout(function () { console.log('i value in closure is ' + index); }, index); } for (var i = 0; i <= 2000; i += 1000) { myTimer(i); }The only difference between your second code block and this expanded code here is that your second code block uses an anonmymous IIFE instead of the named myTimer() function shown here, but the execution is the same. The use of this function inside the for loop creates a Javascript function closure that saves the value of i so that when the setTimeout() calls its callback later, that unique value of i is available to the callback and it does this for each invocation of that function.
The construction:
(function (i) { some async operation here that uses i })(i);is called an immediately invoked function expression (abbreviated IIFE) and is a quick way to create a closure in Javascript.
See this prior answer for more info on the topic: Asynchronous Process inside a javascript for loop
这篇关于了解关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!