javascript - 初学闭包,不太明白,求大神指教
大家讲道理
大家讲道理 2017-06-26 10:58:00
0
7
686
function box() {
    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr[i] = function () {
            return i;
        }
    }
    return arr;
}
var b = box();
for (var i = 0; i < 5; i++) {
    alert(b[i]);
}     

当box()执行完之后,为什么arr[0]到arr[4]里面的值都是function () { return i;}
为什么不依次是:function () {return 0;},function () {return 1;}。。。

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(7)
学习ing

因为闭包只能取得包含函数中任何变量的最后一个值,在这里指的就是i这个变量,box()函数执行后返回的是一个函数数组,数组中的每一个i引用的都是同一个变量i,注意box()返回的是一个函数!所以里面的{return i}这只是函数内的一个声明,还没有执行呀,所以当然保持{return i}不变。因为引用的是同一个外部i,所以当box()函数返回后,外部变量i的值是5,此时每一个return中都引用着保存变量i的同一个变量对象,所以如果最后执行了内部的arr[]中的函数,最后每个函数内部的i的值都是5.

//执行内部返回的arr中的函数,当然box()[1]()、box()[2]()、box()[3]()...都返回5;
    function box() {
        var arr = [];
        for (var i = 0; i < 5; i++) {
             arr[i] = function () {
                return i;
            }
        }
        return arr;
    } 
    box()[1](); //执行后返回5

//不执行内部函数,仅仅是box()的话,当然只返回一个function咯
    function box() {
        var arr = [];
        for (var i = 0; i < 5; i++) {
             arr[i] = function () {
                return i;
            }
        }
        return arr;
    } 
    box(); //[function, function, function, function, function]
伊谢尔伦

因为关联到闭包的作用域链是"活动的". 并且他们共享变量 i , 并不是对每个绑定的变量的值赋值自己单独的一份. 他们只是引用 i,并不会保存 i 每个阶段的值.

参考书籍: JavaScript 权威指南 8.6 小节.

淡淡烟草味

雷雷

世界只因有你

雷雷

阿神

示例中for循环里的function只是赋值,并没有执行,所以当数组中函数执行时才去获取i的值,这时候i只有循环结束的值,楼上没有用到闭包,只是用一个立即执行的匿名函数得到了每个循环的i的值;
方法:1.用ES6 let替代var
function box() {

    var arr = [];
    for (let i = 0; i < 5; i++) {
        arr[i] = function () {
            return i;
        }
    }
    return arr;
}
var b = box();
for (var i = 0; i < 5; i++) {
    alert(b[i]());
}

2.采用闭包
function box() {

    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr[i] = function (x) {
            return function(){
                return x;
            };
        }(i);
    }
    return arr;
}
var b = box();
for (var i = 0; i < 5; i++) {
    alert(b[i]());
}
我想大声告诉你

。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域) ---百度百科
意思就是

function () {
                return i;
            }

这个就是一个代码块,作用仅仅是他引用了i,这样持有i就会导致i不会被释放掉,我们保存的只是这个代码块,这个代码块不运行之前,他根本不知道i是什么东西,就有他运行的时候,他才会去找i,所以你可以把你的arr都输出一下,应该输出的全是5

我想大声告诉你
// arr的元素均是下面这个函数 
function(){
    return i; 
}

调用的时候才计算 i 是什么。

而在调用这些函数的时候,for 已经结束,因此取 for 已经结束,因此取 i 的时候值是 5 的时候值是 5

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板