前端-面试题总结

177 阅读2分钟

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,先执行第一个,后执行第三个参数。可见执行的顺序跟定时器的延时时间也有关。时间相同先执行第三个参数,不同哪个数小先执行哪个