javascript调用方法的奇怪行为

时间:2013-09-07 10:15:43

标签: javascript

我最近正在阅读“有效的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]。 这让我很困惑。为什么我们得到这两个额外的对象。可能,我没有正确地获得呼叫方法。有人可以向我解释发生了什么吗?

2 个答案:

答案 0 :(得分:2)

原因是

table2 = table;
table1 = table;

table2table1引用相同的对象=&gt;您要添加到同一个table对象。

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

{key: key, value: value}

您的最终结果如下:

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

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

答案 1 :(得分:1)

table1table2都引用了table,所以当您致电:

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));