2016-11-10 68 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)