将两个唯一对象推送到空数组会产生一个包含2个等效对象的数组

时间:2015-07-05 00:47:36

标签: javascript arrays object reference

我有以下内容:

var params = {status: [69,71]};

var getTasks = function(params) {
    if (params.status.constructor === Array) {
        var statuses = params.status;
        var newParams = [];

        for (var i = 0; i < statuses.length; i++) {
            params.status = statuses[i];
            newParams.push(params);
        }
        console.log(newParams);

    }
    // else {
    //     ...
    // }
};

getTasks(params)日志newParams称为:

[ { status: 71 }, { status: 71 } ]

我希望这会退出

[ { status: 69 }, { status: 71 } ]

我在这里缺少什么?

4 个答案:

答案 0 :(得分:3)

您按两次相同的对象,可以看到对对象的最新更改。

var obj;
for (var i = 0; i < statuses.length; i++) {
    // construct obj as desired
    obj = {}; // notice this new object is created inside the loop
    obj.status = statuses[i];
    // push to your array
    newParams.push(obj);
}

答案 1 :(得分:2)

newParams.push(params);正在将params引用的对象推送到您的数组。您有一个充满对同一对象的引用的数组,对该对象的任何修改都将出现在每个数组元素中,因为它们都是相同的对象。每次创建一个新对象而不是重用相同的对象:

for (var i = 0; i < statuses.length; i++) {
    newParams.push( { status: statuses[i] } );
}

答案 2 :(得分:2)

params单个对象。在for循环内部,执行以下操作:

for (var i = 0; i < statuses.length; i++) {
    params.status = statuses[i];
    newParams.push(params);
}

...您正在覆盖status字段并将对象推入newParams数组。但是,对象不会被复制 - 而是将引用附加到数组中。因此,newParams的所有元素实际上都是相同的元素。

基本上,您需要将params对象的 clone 推送到循环中的数组中。如果你使用jQuery或下划线,一种简单的克隆方法是使用extend()函数:

// jQuery
newParams.push(jQuery.extend({}, params));
// or Underscore
newParams.push(_.extend({}, params));

答案 3 :(得分:1)

@PaulPro和@PaulS给出了正确的答案,但总有机会学习新的东西。在这种情况下,我建议您查看Array.map,这可以大大简化您的代码:

function statutify(value) {
    return { status: value };
}

var getTasks = function(params) {
    if (params.status.constructor === Array) {
        var newParams = params.status.map(statutify);
        console.log(newParams);
    }
    // ...
};

或者,了解@voithos建议的其他图书馆也不会有什么坏处。