2016-11-10 69 views
3

我有以下代码:如果我在JavaScript中拼接克隆的数组,为什么我的原始数组会拼接?

var coords = [ 
    {lat: 39.57904, lng: -8.98094, type: "a"}, // A 
    {lat: 39.55436, lng: -8.95493, type: "b"}, // B 
    {lat: 39.56634, lng: -8.95836, type: "c"} // C 
]; 

var travelingOptions = []; 

getAllTravelingOptions(); 

function getAllTravelingOptions(){ 
    coords.forEach((point, pos) => { 
     let c = coords; 
     delete c[pos]; 
     console.log(c); 
     console.log(coords); 
    }); 
} 

为什么变量ccoords始终是相同的?如果我在c上删除,它反映在coords上的操作。这是一个正常的行为?

+2

'C'和'coords'是同一个对象都引用。 – Amy

回答

1

由于c的分配,您可以获得数组coords的引用。

coords的任何更改都会影响c,直到将新值分配给c

如果使用Array.slice制作数组的副本,则会得到一个新数组,但具有相同的对象引用。当更改一个对象时,您将在c中使用相同的参考来更改同一个对象。

var coords = [ 
 
     {lat: 39.57904, lng: -8.98094, type: "a"}, // A 
 
     {lat: 39.55436, lng: -8.95493, type: "b"}, // B 
 
     {lat: 39.56634, lng: -8.95836, type: "c"} // C 
 
    ], 
 
    c = coords.slice(); 
 

 
console.log(c); 
 
coords[1].type = 'foo'; 
 
console.log(c);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1

分配并不克隆阵列它仅创建参照原单对象/阵列。您可以使用Array.prototype.slice(),使浅表副本:

let c = coords.slice(); 
1

这是发生,因为ccoords现在引用同一个对象。为防止出现这种情况,请使用let c = coords.slice()创建coords的副本并将其分配给c

let original = [1, 2, 3, 4]; 
 
let test = original; 
 
let testSlice = original.slice(); 
 

 
original[0] = 12345; 
 

 
console.log('test: ', test) 
 
console.log('testSlice: ', testSlice)

然而,新的阵列将仍然引用旧的阵列做了同样的对象。快速解决这个问题就是'克隆'这些对象。

let objs = [ 
 
    {'obj': 1}, 
 
    {'obj': 2}, 
 
    {'obj': 3} 
 
]; 
 

 
let newArr = []; 
 

 
objs.forEach(obj => { 
 
\t let newObj = {}; 
 
\t Object.keys(obj).forEach(key => { 
 
    \t newObj[key] = obj[key]; 
 
    }); 
 
    newArr.push(newObj); 
 
}); 
 

 
console.log('old: ', objs) 
 
console.log('new: ', newArr) 
 

 
newArr[0].obj = 12345; 
 

 
console.log('old after changing obj on new: ', objs)