我有这个构造函数:
var EditableItem = (function() {
function EditableItem(schema, item) {
this.schema = _.clone(schema);
this.item = _.clone(item);
this.propertyTypes = [
'stringProperties',
'booleanProperties'];
}
EditableItem.prototype = {
createItem: function() {
var self = this;
self.propertyTypes.forEach(function(type) {
var properties = self.schema[type];
properties.forEach(function(property, i) {
var itemProperty = self.item[type][property.id];
if (itemProperty) {
properties[i].value = itemProperty;
}
});
});
self.schema.itemId = self.item._id;
return self.schema;
}
};
return EditableItem;
})();
每次我使用它,就像这样...
async.parallel({
schema: function(callback) {
schemas().findOne({
_id: 'default'
}, callback);
},
items: function(callback) {
items().find().toArray(callback);
}
},
function(err, result) {
if (err) return callback(err);
var all = result.items.map(function(item) {
return new EditableItem(result.schema, item).createItem();
});
callback(null, all);
});
...我最终得到一个数组result
,其中最后一项被重复,而其他项被省略。
我的猜测是我需要在某个地方添加一个闭包,正如你所看到的,我已经尝试了,但它仍会产生相同的结果。有什么想法吗?
编辑:我找到了解决方案。它不漂亮,但也许这里有人可以解释它的工作原理并提供更好的解决方案......
在构造函数中,我有: this.schema = _.clone(schema);
我改为: this.schema = JSON.parse(JSON.stringify(schema));
这似乎为对象分配了新的内存,而_.clone仍然保留了对原始对象的一些引用(我猜)。
答案 0 :(得分:0)
Javascript数字,字符串和&布尔值等同并按值传递 ,而对象和数组等同并通过引用传递 。由于对象的JSON表示是一个字符串,因此它将被等同并按值传递。
如果使用schema
的JSON表示给出了克隆(对象)的不同行为,那么我们可以得出结论,克隆仍然包含与原始的,未克隆的schema
相同的对象的引用;即。克隆不是“深层”。
据我了解,underscore.js尚未提供深度克隆,但Lo_Dash确实如此。您可能想尝试Lo_Dash的下划线兼容性构建。
或者,只需坚持使用您的JSON方法,这对您来说就像更正式的深度克隆方法一样。