JavaScript中數組的克隆
擴展運算符...(淺拷貝)
這是在ES6中出現的新的運算符,自從出現以來,它已經成為最受歡迎的方法之一,它的語法實在是太簡潔
numbers = [1, 2, 3];
numbersCopy = [...numbers];
注意:它不能安全的複製多維數組,數組/對象是通過引用複製而不是通過值複製
正例:
numbersCopy.push(4);
console.log(numbers, numbersCopy);
// [1, 2, 3] and [1, 2, 3, 4]
反例:
nestedNumbers = [[1], [2]];
numbersCopy = [...nestedNumbers];
numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1, 300], [2]]
// [[1, 300], [2]]
for循環(淺拷貝)
由於函數式編程的流行,現在應該用的比較少了
numbers = [1, 2, 3];
numbersCopy = [];
for (i = 0; i < numbers.length; i++) {
numbersCopy[i] = numbers[i];
}
注意:它也不能安全地複製多維數組。因為使用=運算符,因此它將通過引用而不是值來分配對象/數組。
正例:
numbersCopy.push(4);
console.log(numbers, numbersCopy);
// [1, 2, 3] and [1, 2, 3, 4]
反例:
nestedNumbers = [[1], [2]];
numbersCopy = [];
for (i = 0; i < nestedNumbers.length; i++) {
numbersCopy[i] = nestedNumbers[i];
}
numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
while循環(淺拷貝)
和for循環類似
numbers = [1, 2, 3];
numbersCopy = [];
i = -1;
while (++i < numbers.length) {
numbersCopy[i] = numbers[i];
}
注意:它也通過引用而不是按值分配對象/數組。
正例:
numbersCopy.push(4);
console.log(numbers, numbersCopy);
// [1, 2, 3] and [1, 2, 3, 4]
反例:
nestedNumbers = [[1], [2]];
numbersCopy = [];
i = -1;
while (++i < nestedNumbers.length) {
numbersCopy[i] = nestedNumbers[i];
}
numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1, 300], [2]]
// [[1, 300], [2]]
Array.map(淺拷貝)
map會將數組轉換成為另一個數組又同時保留結構的方法
numbers = [1, 2, 3];
double = (x) => x * 2;
numbers.map(double);
複製數組就更簡單了
numbers = [1, 2, 3];
numbersCopy = numbers.map((x) => x);
注意:它同樣也通過引用而不是按值分配對象/數組。
Array.filter(淺拷貝)
和map一樣,接受一個函數組作為參數,但是它會通過傳遞的函數過濾和篩選,這樣不能保證得到數組長度不變,比如篩選出數組中的偶數
[1, 2, 3].filter((x) => x % 2 === 0)
// [2]
複製數組
numbers = [1, 2, 3];
numbersCopy = numbers.filter(() => true);
注意:它同樣也通過引用而不是按值分配對象/數組。
Array.reduce(淺拷貝)
reduce 在循環列表時轉換初始值
numbers = [1, 2, 3];
numbersCopy = numbers.reduce((newArray, element) => {
newArray.push(element);
return newArray;
}, []);
注意:它同樣也通過引用而不是按值分配對象/數組。
Array.slice(淺拷貝)
slice需要你傳遞開始索引和結束索引
[1, 2, 3, 4, 5].slice(0, 3);
// [1, 2, 3]
// 0到3索引,得到1,2,3,不包括4
如果只想複製,不需要傳遞任何參數即可
numbers = [1, 2, 3, 4, 5];
numbersCopy = numbers.slice();
// [1, 2, 3, 4, 5]
注意:它同樣也通過引用而不是按值分配對象/數組。
JSON.parse和JSON.stringify(深層拷貝)
- JSON.stringify 將對象轉換為字符串。
- JSON.parse 將字符串轉換為對象。
組合它們可以將對象轉換為字符串,然後反轉該過程可以創建全新的數據結構。
nestedNumbers = [[1], [2]];
numbersCopy = JSON.parse(
JSON.stringify(nestedNumbers)
);
numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1], [2]]
// [[1, 300], [2]]
// 兩個數組是分開的
注意:它是安全的複製方法
Array.concat(淺拷貝)
concat是數組之間相連接,例如
[1, 2, 3].concat(4); // [1, 2, 3, 4]
[1, 2, 3].concat([4, 5]); // [1, 2, 3, 4, 5]
如果只是單純的複製,那你可以不傳遞任何參數或者傳遞一個空數組即可
[1, 2, 3].concat(); // [1, 2, 3]
[1, 2, 3].concat([]); // [1, 2, 3]
注意:它同樣也通過引用而不是按值分配對象/數組。
Array.from(淺拷貝)
可以將任何可迭代對象轉換為數組,如下
numbers = [1, 2, 3];
numbersCopy = Array.from(numbers)
// [1, 2, 3]
注意:它同樣也通過引用而不是按值分配對象/數組。
總結
本文著重探討的是數組的複製,這些方法都可以用來做數組的拷貝,各有好壞,其實還有其他的一些方法來完成數組的複製,本文就介紹到這,如果對你有幫助,請點個關注吧!
相關推薦
推薦中...