闭包

头像
Doyle
    阅读 1 分钟

    一道笔试题

    var arr = ['第一次','第二次','第三次'];
    
    for(var i=0;i<arr.length;i++){
        setTimeout(function(){
            document.getElementById('info').innerHTML = arr[i];
        },i*10000);
    }
    

    你以为这会输出什么?小心别跳入陷阱里。
    结果为:

    1. undefined
    2. 10秒后输出 undefined
    3. 20秒后输出 undefined

    为什么呢?因为i是全局变量,当for循环执行结束后,i当然等于数组长度,所以三次结果都是第三次。实际测试结果都是undefined,因为只有当i=3的时候才结束for循环,而arr[3]表示数组的第四个元素,实际arr数组里只有三个元素,所以arr[3]也就等于undefined

    使用闭包的方式解决

    var arr = ['第一次','第二次','第三次'];
    
    for(var i=0;i<arr.length;i++){
        (function(num){
            setTimeout(function(){
                document.getElementById('info').innerHTML = arr[num];
            },num*10000);
         })(i);
    }
    

    关于setTimeout执行流的问题,这里有一个栗子

    console.log(1);
    setTimeout(function(){console.log(2);},0);
    console.log(3);
    setTimeout(function(){console.log(4);},0);
    console.log(5);
    

    执行结果

    13524
    

    以上执行结果,可以分析到虽然setTimeout得时间设置为0,但setTimeout需要等代码流执行结束后再来执行setTimeout函数块


    Doyle
    844 声望16 粉丝

    前端, angular, vue