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

Pushing two unique objects to an empty array results in an array with 2 equivalent objects

我有以下内容:

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 推送两次,可以看到 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 数组。但是,该对象不会被复制 - 相反,它的 reference 会附加到数组中。因此,newParams 的所有元素实际上是同一个元素。

本质上,您需要将 params 对象的 clone 推入循环中的数组。如果你使用 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 建议的那样学习一些关于其他库的知识也没什么坏处。