分别写出for循环的打印值
for(var i=0;i<5;i++){
console.log(i)
}
for(var i=0;i<5;i++){
(function(i){
console.log(i)
})(i)
}
for(var i=0;i<5;i++){
(function(){
console.log(i)
})(i)
}
for(var i=0;i<5;i++){
setTimeout(function(){
console.log(i)
},i)
}
//01234
//01234
//01234
//55555
当我运行出结果的时候我第一瞬间没有反应过来,为啥最后一个的输出是//55555
脑袋一转从结果出发,明白了!!!
出现55555的原因是setTimeout()中的函数是异步回调的~~并且js是单线程的!
就是在执行下面这段代码时,浏览器执行到setTimeout()时,会将function(){console.log(i)}扔到事件队列中,让他在事件队列中等着,然后继续for循环
浏览器的事件队列当for循环结束后,将要执行事件队列中的回调函数~
回调函数的触发要么是事件,要么是时间。这里是setTimeout(),触发靠的是时间,时间耗光了,回调函数也就执行了,由于在回调函数执行之前,for循环已经结束,i的值是5; console.log(i);也就输出了5。实际代码的执行也可以如下理解:
for(var i=0;i<5;i++){}
setTimeout(function(){ console.log(i) },0);
setTimeout(function(){ console.log(i) },1);
setTimeout(function(){ console.log(i) },2);
setTimeout(function(){ console.log(i) },3);
setTimeout(function(){ console.log(i) },4);
我感觉这样对理解第四个函数的结果就应该很清楚了。
然而第二个,第三个函数,在for循环内自执行,就是在函数体本身加上()和后面加上(),如果要传参,就向第二个()中填写即可,想必有些初学者,对于函数传参会有些疑问:
JavaScript函数是不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型。也就是说,即便你定义的函数值接受两个参数,在调用这个函数时也未必一定要是两个参数。可以传递一个、两个、三个甚至也可以不传参数,而解析器永远不会care。因为JavaScript中的参数在内部是用一个数组来运行的。函数接受到的永远是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,没关系;如果包含多个元素,也没有问题。实际上,在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。
同时还牵扯到JavaScript中作用域的问题,简单的理解:在当前作用域(在这里可以理解为function函数内),如果找不到 i 的值,他就会向父作用域去找,也就是这里的for循环中,所以输出也就很明显了。
网友评论