var arr = [0,1,2];
for(var i =0;i<arr.length;i++){
debugger
setTimeout(function(){
console.log(i);
})
console.log(arr[i]);
}
复制代码
看到群里有人发这题,问打印出来是什么,有个两年工作经验的说输出是3个2,我……
算是经典面试题,答出这题有三个坑要绕,本小白尝试分析一下, 欢迎指正
- var 关键词声明的变量是全局变量,
- js 引用变量其实不是取具体的值而是一个指向,也就是说,它只是存了一个取值的路线,你用的时候它就沿着这条路去取,但是终点的值可能已经被别人改了
- js是单线程,像我这种非专业的人可以理解成,它一次只能处理一件事,其他事要排队等前面的结束后处理,定时器事件会往后排
理解了上面三点以后,我们再来看一下这题,
- for循环执行了三次, 产生了三个定时器,因为上面的单线程问题,所以它们都在事件执行队列的尾巴上等着for循环结束
- 循环体中的console.log事件经历了三次循环,每次打印当前的i值,控制台输出了0, 1, 2。当 i = 3时,不符合 i<arr.length (也就是3)的判断条件,循环结束,此时,全局变量 i 的值 = 3 3.事件队列上终于轮到了定时器事件,定时器里的 i 都沿着循环时存好路径去取值(其实三个 i 存的都是同一个全局对象的存储地址), 取到了全局变量 i = 3
所以,输出结果是 0, 1, 2, 3, 3, 3