js篇
关于setTimeout:
for(var i = 0; i<6; i++){
setTimeout(function(){
console.log(i);
},1000);
}
看到上面的这个for例子,会连续输出6次6,因为setTimeout是一个异步操作,而等到执行setTimeout时,for循环已经执行完毕,这时的i已经等于6,所以输出6次的6。
闭包
for(var i=0; i<6; i++){
(function(j){
setTimeout(function(){
console.log(j);
},1000);
})(i);
}
通过闭包,将i的变量驻留在内存中,当输出j时,引用的是外部函数的变量值i,i的值是根据循环来的,执行setTimeout时已经确定了里面的的输出了。相当于
(function(0){
setTimeout(function(){
console.log(0)
},1000)
})(0)
(function(1){
setTimeout(function(){
console.log(1)
},1000)
})(1)
...
(function(9){
setTimeout(function(){
console.log(9)
},1000)
})(9)
函数传参
给setTimeout添加第三个参数
for(var i=0;i<6;i++){
setTimeout(function(j){
console.log(j);
},i*1000,i);
}
由于每次传入的参数是从for循环里面取到的值,所以会依次输出0~5。它就是给setTimeout第一个函数的参数。setTimeout第三个及后面的参数都将作为参数传递给第一个函数参数。
如果setTimeout的第三个参数作为函数
var i=0;
setTimeout(function(){
console.log('第二次'+i)
i++;
},3000,setTimeout(function(){
console.log('第一次'+i);
i++;
},1000));
输出结果为 第一次0,第二次1,第三个参数先执行,然后再执行第一个参数;如果定时器的时间改一下呢
var i=0;
setTimeout(function(){
console.log('第二次'+i)
i++;
},1000,setTimeout(function(){
console.log('第一次'+i);
i++;
},3000));
输出的结果为 第二次 0 ,第一次 1,先执行第一个,后执行第三个参数。可见执行的顺序跟定时器的延时时间也有关。时间相同先执行第三个参数,不同哪个数小先执行哪个