我在我的应用程序中观察(对我来说)不可解释的行为。 我有几个包括via require()。在其中一个名为“addUserFunction.js”中,我有两个函数和一个包含对象的数组 这是objects-array的定义:
exports.itemList = [{itemType:"info",itemName:"Information"},{...},{...}];
这是两个函数的定义:
exports.getItem = function(data) {
var returnItem = {};
for (var i=0;i<exports.itemList.length;i++) {
if (exports.itemList[i].itemType == data.itemType){
returnItem = exports.itemList[i]; // This line seems to pass a reference, not assign/copy
}
}
returnItem.itemName = (data.itemName) ? data.itemName : returnItem.itemName;
return returnItem;
}
exports.createPlan = function(formValues) {
var returnItem = {
id: 0,
description: 'foobar',
items: [
exports.getItem({itemType:'info',itemName:'Information'}),
exports.getItem({itemType:'somethingelse'}),
exports.getItem({itemType:'bla',itemName:'yougottheidea'})
]
};
return returnItem;
}
现在问题是:只要我使用函数exports.getItem
并覆盖某些属性,getItem
似乎就会将新创建的returnItem
与原始itemList[i]
相关联}。因此,itemList[i]
的下一次调用将使用第一次调用的属性值。希望被解释可以理解。
怎么会这样?
createPlan()
从另一个required()
文件调用,如下所示:
var aF = require('addUserFunctions');
function addUser() {
var formValues = {name: 'test'};
formValues.foo = aF.createPlan(formValues);
}
module.exports = addUser;
答案 0 :(得分:1)
无论何时为对象(包括所有类型的对象,甚至是数组)分配变量或属性,分配的内容都是对象实例的引用值。也就是说,如果我有
a = {};
b = a;
然后是a.foo = 1
,然后是b.foo === 1
。但是如果你做a = null;
,b仍然指向它之前指向的同一个对象。您在代码中所做的只是挖掘数组,找到合适的条目,返回对该条目的引用。你打算做的是使用该引用作为创建新对象的模板。有几种方法可以创建这样的对象。最常见的方法是使用公共库的extend
方法之一。但是,如果您的对象深度超过一级,或者您的对象由除了普通对象之外的其他对象组成,则事情可能会变得棘手,并且可能无法使用这些通用方法创建对象的深层副本,只有浅层的。
最简单的方法是修改您的getItem
以克隆您的模板,特别是将您需要的属性复制到新对象中。如果模板中的任何属性引用了某些可能需要副本的对象,请务必复制该对象。
答案 1 :(得分:0)
原因是我没有复制元素,我只链接到它,因为它是我想要复制的对象。 =
不复制对象,只复制简单的变量类型,如数组,整数,布尔值等。
我创建了一个知道该对象结构的新函数,并按属性复制属性:
exports.copyListItem = function(item) {
var newItem = {};
newItem.itemType = item.itemType;
newItem.itemName = item.itemName;
// and so on
return newItem;
}
不是最优雅的方式,但它的工作原理。有关更一般的方法,请查看此处:Most elegant way to clone a JavaScript Object
我正在回答我自己的问题,因为原来的回答只是一个评论,对我的反评论没有反应(到目前为止)。