JavaScript拼图:范围

use*_*031 4 javascript variables scope

所以我想弄清楚这个难题:

function fun1(){
    var result = [];
    for (var i = 0; i < 5; i++){
        result.push( function() {return i} );
    }
    return result;
}

console.log(fun1()[0]()) // returns 5?
Run Code Online (Sandbox Code Playgroud)

不应该该数组的第一个元素返回一个返回'0'的函数?

小智 6

不,它应该返回5.

该函数仍然具有对i的引用,其后为5.

  • 我不明白的是为什么.里面的函数仍然在'for'循环内,而不是在它之外,那么为什么它在循环之后返回i的值? (3认同)

I a*_*ica 6

这是因为你的函数(闭包)维护了一个

  • 参考 i

而不是

  • i每个特定迭代期间存在的快照.

这意味着您的函数在执行时将知道该i瞬间的当前值.因为循环已经在那一点完成,所以这将是i循环设置的最后一个值.那么,我们如何获取快照而不是参考?幸运的是,数值参数是按传递的...所以,你可以通过传递i给第二个函数来避免你的问题......(小提琴):

function fun1(){
    var result = [];
    for (var i = 0; i < 5; i++){
        (function(x){
            result.push(function() { 
                return x; // x now has i's snapshotted value
            });
        })(i); // passes i by value since it's numeric
    }
    return result;
}

alert(fun1()[0]())
Run Code Online (Sandbox Code Playgroud)

[编辑]让我们从循环中取出循环(小提琴):

var i = 1;
var fn = function() { // this closure maintains a reference to i 
    alert(i); 
};
i = 10; // such that when we change i's value here
fn(); // it's reflected by the function call: alerting 10
Run Code Online (Sandbox Code Playgroud)

所以,要"修复"这个(小提琴):

var i = 1;
var fn = (function(x) { // this is a self-executing anonymous function
    return function() { // this closure maintains a reference to x
        alert(x); 
    };
})(i); // we're passing i by value such that x will retain that value
i = 10; // when we change i here, it has no affect on x
fn(); // this will alert 1
Run Code Online (Sandbox Code Playgroud)