Javascript将array设置为另一个数组元素的属性

时间:2014-11-30 15:41:34

标签: javascript arrays

我想创建一个父数组和另一个子数组,然后为每个父项设置一个子数组。

以下是代码:

var parent = [];
var child = [];

// Set kids
for (a = 0; a <= 5; a++) {
    child[a] = [];
    child[a].name = "kid " + a;
}

// Set parents and their kids
for (b = 0; b < 2; b++) {
    parent[b] = [];
    parent[b].name = "parent " + b;
    parent[b].kids = child;
}

// One parent has kid name anna
parent[0].kids[2].name = "anna";

// Output
for (a = 0; a < 2; a++) {
    console.log("");

    for (b = 0; b < 5; b++) {
        console.log(b + " -> " + parent[a].name + " " + parent[a].kids[b].name);
    }
}

第一位父母

0 - &gt;父母0孩子0

1 - &gt;父母0孩子1

2 - &gt;父母0安娜

3 - &gt;父母0孩子3

4 - &gt;父母0孩子4


第二位父母

0 - &gt;父母1孩子0

1 - &gt;父母1孩子1

2 - &gt;父母1安娜

3 - &gt;父母1孩子3

4 - &gt;父母1孩子4


为什么父母双方都有相同的孩子,只有第一个孩子应该有孩子名称anna,更重要的是如何让它正常工作?

2 个答案:

答案 0 :(得分:1)

因为您在新创建的对象中传递了对数组的引用。

var a = [1,2,3,4];
var b = a;
b[0] = 2;
a[0] === 2; // true

为了发送一个新阵列(克隆)。你可以这样做:

for (b = 0; b < 2; b++) {
    parent[b] = [];
    parent[b].name = "parent " + b;
    parent[b].kids = child.slice(); // Slice creates a new array from the old
}

编辑1

正如@dfsq在提供的原始问题和代码中所述,您实际上使用的是对象而不是数组。如果不深入讨论克隆对象的最佳方法,我们假设您在代码中使用了jQuery,在这种情况下您可以安全地执行:

parent[b].kids = $.extend({}, child);

有关使用Mozilla Developer Network中可以阅读的对象的更多信息。

答案 1 :(得分:1)

如前所述,您的问题是为每个父母分配相同的子数组。

如果数组child包含原始值,则使用任何方式复制数组然后设置kids属性实际上会有所帮助,因为浅拷贝就足够了。但是,这里提出的问题有点复杂,因为元素不是原语,所以应该使用深度复制的方法。

更具体地说,不仅需要复制整个数组,还需要单独制作每个项目的副本。

每次将其分配给父级时,您都可以尝试使用此类复制子项。这不是最快的方法,但应该足够好开始。

function clone(obj) {
    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = obj.constructor(); // changed

    for(var key in obj) {
        if(obj.hasOwnProperty(key)) {
            temp[key] = clone(obj[key]);
        }
    }
    return temp;
}

function copy_kids(kids) {
    var new_kids = [];
    for (var kid_id = 0; kid_id < kids.length; ++kid_id) {
        new_kids[kid_id] = clone(kids[kid_id]);
    }
    return new_kids;
}

复制对象的功能取自older answer

要使代码生效,请更改以下内容:

// Older
parent[b].kids = child;

// Newer
parent[b].kids = copy_kids(child);

要完全准确,这不是真正的深度复制,而是比复制数组本身稍微深一点。您可以阅读有关深复制和浅复制here的更多信息。