在js中let和var有个用法让人很疑惑,很多人搞了很久都没有搞懂,就是下面两个例子:
for (var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); }, 100 * i); }
输出结果:
for (let i = 0; i < 10; i++) { setTimeout(function() { console.log(i); }, 100 * i); }
输出结果:
上面两段代码的差别就是变量i声明的时候,第一段代码是var,第二段代码是let,就仅仅是这个差别,为什么导致结果差别这么大呢?
为了方便解释,我在两段代码上分别加上了log,再看看输出结果:
for (var i = 0; i < 10; i++) { console.log("outside"); setTimeout(function() { console.log("inside"); console.log(i); }, 100 * i); }
for (let i = 0; i < 10; i++) { console.log("outside"); setTimeout(function() { console.log("inside"); console.log(i); }, 100 * i); }
从上面的输出结果可以看出,这段代码是先将for循环全部执行完了之后再执行setTimeout的,差别就在这里。
对于用var声明的变量来说,是没有块级作用域的概念的,i在全局范围内有效,而全局只有一个i变量,每循环一次i就改变一次,到最后i = 10,再执行setTimeout时,i已经为10,所以输出的i为10;
而let声明的变量是有作用域的概念的,let声明的变量只在块级作用域有效,所以当前的i只在本轮循环有效,每次循环i其实都是一个新的变量,所以最后输出的会是0~9。
在不支持let的地方,上面的问题还有一种解法,就是立即执行函数,代码如下:
for (var i = 0; i < 10; i++) { console.log("outside"); (function(i){ setTimeout(function() { console.log("inside"); console.log(i); }, 100 * i); })(i); }
欢迎大家指教~