3

我最近正在阅读“Effective javascript”。在“使用自定义接收器的调用方法”项中。作者提供了一个使用这种方法将一个表的内容添加到另一个表的示例:

var table = {
    entries: [],
    addEntry: function(key, value) {
        this.entries.push({key: key, value: value});
    },
    forEach: function(f, thisArg) {
        var entries = this.entries;
        for (var i = 0, n = entries.length; i < n; i++)
        {
            var entry = entries[i];
            f.call(thisArg, entry.key, entry.value, i);
        }
    }
};

现在,如果我测试这个方法,编写如下内容:

table2 = table;
table1 = table;
table1.entries = [1, 3];
table1.forEach(table1.addEntry, table2);
console.log(table2.entries);

我将 table2 条目的内容作为 [1, 3, Object, Object]。这让我很困惑。为什么我们会得到这两个附加对象。可能是我没有正确获取调用方法。有人可以向我解释发生了什么吗?

4

2 回答 2

2

原因是

table2 = table;
table1 = table;

table2table1引用同一个对象 => 您要添加到同一个table对象。

您得到最后两个对象是因为您的添加条目创建了新对象:

{key: key, value: value}

您的最终结果如下所示:

[1, 3, {0:1}, {1:3}]

{0:1},{1:3}: 0,1 是索引

于 2013-09-07T10:23:51.743 回答
1

table1和参考table2table所以当你打电话时:

table1.entries = [1, 3];

它实际上也添加了这些条目table2

要解决此问题,请使用new关键字:

table2 = new table;
table1 = new table;

此外,你得到类似[1, 3, Object, Object]而不是的原因[1, 3, 1, 3]是因为该addEntry方法添加了一个对象,而不是像你所做的那样只添加数字:

{key: key, value: value}

所以每个条目的格式实际上是一个对象。

如果您希望能够看到有意义的东西而不是Object,请对条目数组进行字符串化:

console.log(JSON.stringify(table2.entries));
于 2013-09-07T10:24:34.377 回答