我最近正在阅读“有效的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]。 这让我很困惑。为什么我们得到这两个额外的对象。可能,我没有正确地获得呼叫方法。有人可以向我解释发生了什么吗?
答案 0 :(得分:2)
原因是
table2 = table;
table1 = table;
table2
和table1
引用相同的对象=&gt;您要添加到同一个table
对象。
您获得最后两个对象是因为您的添加条目创建了新对象:
{key: key, value: value}
您的最终结果如下:
[1, 3, {0:1}, {1:3}]
{0:1},{1:3}
:0,1是索引
答案 1 :(得分:1)
table1
和table2
都引用了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));