-1

我有这个构造函数:

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 仍然保留了对原始对象的一些引用(我猜)。

4

1 回答 1

0

Javascript 数字、字符串和布尔值相等并按值传递,而对象和数组相等并按引用传递。由于对象的 JSON 表示是一个字符串,因此它将被等同并按值传递。

如果使用 的 JSON 表示会schema给出与克隆(对象)不同的行为,那么我们可以得出结论,克隆仍然包含对与原始对象相同的对象的引用,未克隆schema;IE。克隆不是“深”的。

据我了解,underscore.js 尚未提供深度克隆,但Lo_Dash提供。您可能想尝试 Lo_Dash 的下划线兼容性构建。

或者,只需坚持使用 JSON 方法,这与更正式的深度克隆方法相同。

于 2013-05-10T01:19:15.657 回答