3

我不明白这个范围是如何工作的。仅在 in 中修改时,如何eg.i修改 in的值?firstsecond

例子

var obj = {

    first: function() {

        var eg = {i: 0}; // eg equals 0 here

        obj.second(eg);
        obj.second(eg);

        console.log(eg.i); // 2
    },

    second: function(eg) {

        ++eg.i;
    }
};

如何eg.i在第一个函数中进行修改?

4

3 回答 3

4

当对象被传递给 JS 中的函数时,它们作为引用而不是值被传递: http: //snook.ca/archives/javascript/javascript_pass

于 2013-06-02T20:10:50.233 回答
4

正如我在对 Ahmed Nuaman 的回答的评论中指出的那样,说参数通过引用传递是不正确的。证明这是微不足道的:

function change (x) {
    //"replace" x with a different object?
    x = {
        a : 4
    };
}
var o = { a : 6 };
change(o);
console.log(o.a); //6

如果参数真的是通过引用传递的,o.a那么应该是4. 但是,参数是通过引用传递的——在这种情况下,值只是对象。

这就是为什么您观察到问题中出现的症状:当您直接修改参数时,传入的对象已更改。

就好像你买了一些冰淇淋,然后回到摊位上要额外的一勺香草。你仍然有同样的杯子,但有额外的东西。使用上面示例中的类比,您要求一个新的香草冰淇淋:您仍然有旧的,并且没有改变(嗯,它可能已经融化了一点)。在通过引用的场景中,您会丢弃现有的冰淇淋,并得到一个全新的冰淇淋。

最后一点:这与 js 中的范围规则无关。如果eg没有传递给该second函数,它将不可用。

于 2013-06-02T20:36:56.720 回答
3

您将eg作为参数传递给second. 如果您重命名它可能更容易查看:

second: function(x) {
    ++x.i;
}

它在第一个函数中被修改,因为您使用第二个函数对其进行了修改。

于 2013-06-02T20:10:07.433 回答