Array.push用插入的最后一个数组替换所有数组元素

时间:2015-10-22 13:45:36

标签: javascript jquery

我有以下代码:

var ship_array = new Array();

var ship_object = new Object();
    ship_object.builder_id = 0;
    ship_object.list_id = 0;
    ship_object.ship_id = 0;
    ship_object.title_id = 0;

然后在保存功能中,我这样做:

function saveAll() {
    // Array cleaning
    while (ship_array.length) { ship_array.pop(); }

    // Cyclic save function
    $.each($(".ship-block"), function () {
        ship_object.builder_id = parseInt($(this).attr("data-counter"));
        ship_object.list_id = list.id;
        ship_object.ship_id = parseInt($(this).attr("data-ship-id"));
        ship_array.push(ship_object);
    });
    console.log(ship_array);
}

使用Chrome进行调试时,每个ship_object在每个循环中都有正确的值,但是当我打印数组时,每个对象都具有相同的值,这些值都与插入的最后一个对应。字面上不知道为什么会发生这种情况。想法?

4 个答案:

答案 0 :(得分:2)

基本上,您正在使用对象的引用并一次又一次地更新同一对象。每次循环迭代时尝试创建一个新对象,

function saveAll() {
    //while (ship_array.length) { ship_array.pop(); }
    ship_array = [];
    $(".ship-block").each(function () {
        ship_object = {}; // creating a new object here!!
        ship_object.builder_id = parseInt($(this).attr("data-counter"));
        ship_object.list_id = list.id;
        ship_object.ship_id = parseInt($(this).attr("data-ship-id"));
        ship_array.push(ship_object);
    });
    console.log(ship_array);
}

答案 1 :(得分:1)

你必须克隆你的对象:

$.each($(".ship-block"), function () {
  var object = $.extend({}, ship_object);
  object.builder_id = ...
});

答案 2 :(得分:1)

在您的代码中,您的数组包含对同一对象的引用,您只更新该对象的属性。

您应该为每个数组元素创建一个新对象。请注意,您可以使用对象文字语法,如下所示:

function saveAll() {
    // Array cleaning
    ship_array = [];

    // Cyclic save function
    $.each($(".ship-block"), function () {
        var ship_object = {
            builder_id: parseInt($(this).attr("data-counter")),
            list_id: list.id,
            ship_id: parseInt($(this).attr("data-ship-id"))
        };
        ship_array.push(ship_object);
    });
    console.log(ship_array);
}

请注意,我还使用新的空数组([])重新初始化数组,而不是在循环中弹出它。

答案 3 :(得分:1)

这是由于函数范围,您的指针正在被重用,并且指针被推送到堆栈而不是它指向的对象。在回调中使用对象文字应该避免重用任何指针。并解决问题。

function saveAll() {
    // Array cleaning
    while (ship_array.length) { ship_array.pop(); }

    // Cyclic save function
    $.each($(".ship-block"), function () {
        ship_array.push({
          builder_id: parseInt($(this).attr("data-counter")),
          list_id: list.id,
          ship_id: parseInt($(this).attr("data-ship-id"))
        });
    });
    console.log(ship_array);
}