J 筆記 - Clone an Array
複製陣列及資料,不管在什麼語言當中,都是很常用到的方式,在了解如何複製之前,應該對所謂的「傳值」、「傳址」大概的了解,才知道為什麼這樣能複製一個新的陣列出來,而不是改到之前的陣列…
重新認識 JavaScript: Day 05 JavaScript 是「傳值」或「傳址」?
ES6 Way to Clone an Array
舊有的複製陣列通常都以 slice
來達成,不過 ES6 後,有些其他的方法可以快速複製,就來看看吧…
1 2 3 4 5 6 7 8
| const initarray = ['ES5', 'ES6', 'ES7'];
const oldarray = initarray.slice();
const spreadoperator = [...initarray]; const Arrayfrom = Array.from(initarray);
|
還記得上次的 String to Array 也有用到 spread operator
、Array.from
兩者用法,如果忘記得可以再去看看
Call by value / Call by address
JS 中的數組是 Call by value
,因此如果嘗試使用 =
進行複制時,只會複製到原始宣告的那組數組,而不是數組的值。要真正複製一個全新數組,需要在新的 value 下複製數組的值,這樣就不會引用內存中的舊 address。
1 2 3 4 5 6 7 8 9 10
| const initarray = ['ES5', 'ES6', 'ES7'];
const errormethod = initarray; const spreadoperator = [...initarray];
console.log(initarray === errormethod);
console.log(initarray === spreadoperator);
|
initarray Problem
看完了上面的例子,可能還是搞不太懂 true / false 帶來的影響,或許知道了就是在不同的 memory space
,且慢看看下面的例子:
1 2 3 4 5 6 7 8 9 10 11
| const initarray = ['ES5', 'ES6', 'ES7'];
const initarray2 = initarray;
initarray2.push('❌');
console.log(initarray2);
console.log(initarray);
|
有發現最初的陣列也被改掉了嗎?明明是要複製全新的陣列然後 push
東西進去,但為什麼原本的陣列也被改掉了!
這就是「傳值」、「傳址」的差別:
1 2 3 4 5 6 7 8 9 10 11
| const initarray = ['ES5', 'ES6', 'ES7'];
const initarray2 = [...initarray];
initarray2.push('✔️');
console.log(initarray2);
console.log(initarray);
|
Only one level
Note!!! 記得 Spread operator
、Array.from()
兩者複製陣列時只能深入一層,如果要更深入,必須要用其他方法才能達成!
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const initarray = [['ES5', 'ES6'], ['ES7']];
const spread_operator_array = [...initarray]; const Array_from_array = Array.from(initarray);
spread_operator_array[0][0] = "❌"; Array_from_array[0][0] = "❌";
console.log(spread_operator_array); console.log(Array_from_array);
console.log(initarray);
|
參考資料