先看一段代码,并想出本人的答案:
for(var i=0;i<5;i++){setTimeout(function(){console.log(i);
},1000)
}
console.log(i);
不难得出,该题的答案是 5 5 5 5 5 5。
立刻输入一个 5,1 秒后输入 5 个 5。
如果这里想把答案变成:5 1 2 3 4 5。
那么,相熟闭包的同学,很快能够得出一个这样的办法:
for(var i=0;i<5;i++){(function(j){ //j = i
setTimeout(function(){console.log(j);
},1000)
})(i);
}
console.log(i);
如果对定时器很理解的话,咱们还能够用另一种形式:
for(var i=0;i<5;i++){setTimeout(function(j){console.log(j);
},1000,i)
}
console.log(i);
这里的 setTimeout 的第三个参数是可选项,示意提供给以后执行函数的其余参数
当然如果相熟 ES6 语法,很快就会想到将 var 改成 let,代码如下:
for(let i=0;i<5;i++){setTimeout(function(){console.log(i);
},1000)
}
console.log(i);
当然这种办法会报错,因为 i 值只在块级作用域内失效;
然而这种办法的确能够将定时器内打印进去的后果改为 1 2 3 4 5
闭包,艰深的来讲就是一个函数能够拜访另一个函数中的变量,防止变量被垃圾回收机制给回收。
最常见的闭包就是函数外部加一个子函数,通过子函数拜访函数的局部变量。