js闭包进阶

在了解一定闭包知识的基础上,再来一个题:

function test(){
    var arr = [];
    for(var i = 0; i < 10; i++){
        arr[i] = function(){
            document.write(i + " ");
        }
    }
    return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){
    myArr[j]();
}

试试猜测结果。
分析: 一看return,闭包,没跑了。跟着test里面的i走就完事了,一个递增 0 1 2 3 4 5 6 7 8 9
美滋滋


但是我们发现又错了(;′⌒`)
原因:在执行 var myArr = test()的时候,只执行了test()函数,也就是说,在返回出来的myArr数组中,每一位就是一个函数,具体是啥函数,不知道。直到myArrj的时候,里面的documen.write才执行,那时i的值是从test的AO里找到的,再循环之后i 的值是10,所以最后的结果: 10 10 10 10 10 10 10 10 10 10 。




知道原因还不够,我们如果想要一开始的结果,我们就得解决他。
首先:飘逸解决法:

function test(){
    var arr = [];
    for(var i = 0; i < 10; i++){
        arr[i] =i
    }
    return arr;
}
var myArr = test();
for(var i = 0; i < 10; i++)
{
    document.write(myArr[i]);
}

直接顺着循环赋值,最后调用时再打印。
但是我们本着深度学习的目的,这种方法显然不是我们想要的。就是想在test函数里调用打印,怎么办?


function test(){
    var arr = [];
    for(var i = 0; i < 10; i++){
       ( function(j){
            arr[j] = function(){
                document.write(j + ' ');
            }
        }(i));
    }
    return arr;
}
var myArr = test();
for(var k = 0; k < 10; k++){
    myArr[k]();
}

分析:

  1. 首先我们能看到(function (j){}())立即执行函数。

  2. for 中i作为实参传进,arr….每次执行都能拿到外部(立即执行函数)的AO,所以每次在for循环里递增的i会被保存到立即执行函数的作用域里,从而被里层函数所调用,实现递增打印。

感谢访问!

你可能感兴趣的:(javascript,学习,javascript,闭包)