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



我有以下内容:

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 } ]

我在这里错过了什么?

如果两次推送相同的对象,则可以看到对Object的最新更改。

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);
}

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

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

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

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

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

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

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

@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建议的那样,了解其他图书馆也无妨。

最新更新