记一次面试

关于一道常常碰到的面试题

最近面试常常碰到这样一道题(或者相似):ps.由于我阿姨不会就详细分析吧。es6

var btns = document.getElementsByClassName('btn');
    for(let i = 0; i < btns.length; i++){
        btn[i].onclick = function(){
            console.log(i)
        }
    }

这个以前说过,由于面试的时候,说了主要看闭包。因此也没有多想。面试

function fun(){
    for (var i = 0; i < 5; i++){
        setTimeout(()=>{
            console.log(i)
        },0); 
    }
}
fun();

问题

其实,经过分析就不难看出,核心点问题都是, 在一个循环内,延时打印循环变量。 全部的结果同样。promise

问题分析

由于js的变量有提高做用,因此能够将程序改为成更加直观的形式。闭包

var i = 0; 
function fun(){
    while (i < 5){
        setTimeout(()=>{
            console.log(i) // 这里访问的i 都是 以前定义的 i
        },1000); 
        i++;       // 这里访问的i 也是 以前定义的 i
    }
}
fun();

咱们改为程序以后,就能够看到了。 打印语句的i,由于都是在等待i变换以后,取i值打印, 因此结果同样。函数

问题缘由

这里产生问题的缘由在于:code

  1. for语句不会像其余语言具备块级做用域(也是js变量声明提高)。
  2. 全部的访问循环变量的值,都是延时访问了。
  3. 访问的i都指向同一个i。

解决方法

其实,核心问题,就是等待循环结束,才去访问i,并且访问的是同一个i。
解决思路:两种 改变访问时机, 改变访问变量。作用域

在改变以前访问i。

for( var i = 0; i < 5; i++){
    console.log(i);
}

这样作好像没什么意义。get

为每一语句保存一个i值

  1. 让for语句具备块级做用域
    这是es6的语法规则: 使用let. (这是最简单的一种形式)
function fun(){
    for (let i = 0; i < 5; i++){
        setTimeout(()=>{
            console.log(i)
        },0); 
    }
}
fun();

用let代替var来声明变量,就能够把变量的做用域限制在当前代码块中也就是{}io

  1. 使用闭包
    函数是具备本身的做用域的。在es6以前,都是使用闭包来实现块做用域
function fun(){
    for (var i = 0; i < 5; i++){
        setTimeout((function(i_){
            return function(){
                console.log(i_)
            }
        })(i),0); 
    }
}
fun();

其实, 也就是用 当即执行函数参数i_ 来保存 i 值 。 固然你也能够把i_写成i。console


分割线(这对以前问题的处理)

  1. 使用setTime调用时候能够传递参数的特性。
    难道以前面试问个人是这么作?
function fun(){
    for (var i = 0; i < 5; i++){
        var promise = new Promise(function(resolve, reject){
            setTimeout(resolve,1000,i); 
        }); // 这个是当即执行
        promise.then(function(value){  // 回调执行
            console.log(value);
        })
    }
}
fun();

下面代码也能够实现,其实,你就会发现, 这是由于 setTimeout 函数 能够调用给函数传递参数的缘由, 。

function fun(){
    for (var i = 0; i < 5; i++){
        setTimeout((i)=>{
            console.log(i)
        },0,i); 
    }
}
fun();
相关文章
相关标签/搜索