通过Array.prototype.slice()更改克隆数组会影响原始数组

时间:2016-01-25 21:23:25

标签: javascript arrays

function ConwayNeighbours(a) {
var b = a.slice()
for(i=0; i<a.length; i++)
for(j=0; j<a[i].length; j++){

    if(a[i][j+1])
        b[i][j]++
    if(a[i][j-1])
        b[i][j]++

    if(a[i-1]){
        if(a[i-1][j])
            b[i][j]++
        if(a[i-1][j+1])
            b[i][j]++
        if(a[i-1][j-1])
            b[i][j]++
    }

    if(a[i+1]){
        if(a[i+1][j])
            b[i][j]++
        if(a[i+1][j+1])
            b[i][j]++
        if(a[i+1][j-1])
            b[i][j]++
    }
console.log("i",i,"j",j,"a",a,"b",b)
}

return b
}
ConwayNeighbours([[false,true],  [true,true]])

我的问题是为什么以及如何更改数组a,我没有做任何影响,我确保通过slice克隆它,从原始数组返回一个新数组,有人可以解释

2 个答案:

答案 0 :(得分:2)

Slice返回一个数组的浅表副本,因此如果你有一个数组数组,那么数组引用将按原样复制。根据数据成员的类型,执行数组深层副本的一个快捷方式是执行以下操作而不是b=a.slice()

var b = JSON.parse(JSON.stringify(a));

或者,您可以使用递归数组深度克隆功能,例如by Andrew Ray

function arrayClone( arr ) {

    var i, copy;

    if( Array.isArray( arr ) ) {
        copy = arr.slice( 0 );
        for( i = 0; i < copy.length; i++ ) {
            copy[ i ] = arrayClone( copy[ i ] );
        }
        return copy;
    } else if( typeof arr === 'object' ) {
        throw 'Cannot clone array containing an object!';
    } else {
        return arr;
    }

}

答案 1 :(得分:1)

Javascript通过引用传递,var a包含嵌套数组。您只对B的顶级数组进行切片(和ergo复制),但该值仍然是A中包含的数组。您可以在控制台中轻松测试:

var a = [[1,2,3,4]]
var b = a.slice()

b === a //false
b[0] === a[0] //true