Open duyue6002 opened 5 years ago
for (var i = 1; i < 5; i++) { setTimeout(function timer() { console.log(i); }, i*1000); }
运行时,以每秒一次的频率输出5,与输出期望值(1 2 3 4)不同。
延迟函数的回调发生在循环结束时才执行,即使setTimeout(.., 0)结果也相同。循环不会等待回调 实际上,代码可以被看作:
setTimeout(.., 0)
var i; for (i = 1; i < 5; i++) { setTimeout(function timer() { console.log(i); }, i*1000); }
标识符i属于全局变量,尽管每个循环都定义了延迟函数,但它们都被封闭在一个全局作用域中,共享同一个i的引用。
i
在这段代码中,需要更多的闭包作用域,每次迭代都需要一个作用域。 解决 块作用域拥有自己的变量,用来存储i的值 使用立即执行函数 for (var i = 1; i < 5; i++) { (function(j) { setTimeout(function timer() { console.log(j); }, j*1000); )(i); } 使用ES6 for (let i = 1; i < 5; i++) { setTimeout(function timer() { console.log(i); }, i*1000); } let循环在每次迭代时,都会进行重新绑定的行为,let声明附属于新的作用域而不是当前的作用域代码相当于: let i; for (i = 1; i < 5; i++) { let j = i; setTimeout(function timer() { console.log(j); }, j*1000); } ES6大法好!!
在这段代码中,需要更多的闭包作用域,每次迭代都需要一个作用域。
块作用域拥有自己的变量,用来存储i的值
for (var i = 1; i < 5; i++) { (function(j) { setTimeout(function timer() { console.log(j); }, j*1000); )(i); }
for (let i = 1; i < 5; i++) { setTimeout(function timer() { console.log(i); }, i*1000); }
let循环在每次迭代时,都会进行重新绑定的行为,let声明附属于新的作用域而不是当前的作用域代码相当于:
let
let i; for (i = 1; i < 5; i++) { let j = i; setTimeout(function timer() { console.log(j); }, j*1000); }
ES6大法好!!
由循环中的闭包引发的血案
运行时,以每秒一次的频率输出5,与输出期望值(1 2 3 4)不同。
原因
延迟函数的回调发生在循环结束时才执行,即使
setTimeout(.., 0)
结果也相同。循环不会等待回调 实际上,代码可以被看作:标识符
i
属于全局变量,尽管每个循环都定义了延迟函数,但它们都被封闭在一个全局作用域中,共享同一个i
的引用。