## 14 個(gè)拷貝數(shù)組的 JS 技巧
[100素材網(wǎng)](javascript:void(0);) *今天*
以下文章來(lái)源于大遷世界 ,作者前端小智
[
**大遷世界**
我要先堅(jiān)持分享20年棍厌,大家來(lái)一起見(jiàn)證吧甸昏。](https://mp.weixin.qq.com/s?__biz=MzIwMDYyOTE1NA==&mid=2650235209&idx=1&sn=15b50e7be88f519894e5de6b84193bc0&chksm=8ef98f84b98e06921ab76a14e247ce2de5b58e5ecf7747816027840da91e0b38e7d80cfeba51&scene=0&xtrack=1&key=d6a080855538065e07da9c82810d3c8d3e6df0670621cf04fbfa937a23c71a8d17487cc1d56299da9cbdad48c5d967a62caaa9c8226ca999c865209984ad6ed37e88a39b966aee8fdba8b13ad751e479&ascene=1&uin=MjI2MDA3ODQyMw%3D%3D&devicetype=Windows+7&version=62060834&lang=zh_CN&pass_ticket=csPtwbpfBJsy5STsuFnc%2FYJNBhJY53roQGyuZ3k1GqhrFnaRV1nYVGlJZHH8sC3Y&winzoom=1#)
**為了保證的可讀性膀懈,本文采用意譯而非直譯。**
數(shù)組拷貝經(jīng)常被誤解漓踢,但這并不是因?yàn)榭截愡^(guò)程本身,而是因?yàn)槿狈?duì) JS 如何處理數(shù)組及其元素的理解。JS 中的數(shù)組是可變的午乓,這說(shuō)明在創(chuàng)建數(shù)組之后還可以修改數(shù)組的內(nèi)容。
這意味著要拷貝一個(gè)數(shù)組闸准,咱們不能簡(jiǎn)單地將舊數(shù)組分配給一個(gè)新變量益愈,它也是一個(gè)數(shù)組。如果這樣做,它們將共享相同的引用蒸其,并且在更改一個(gè)變量之后敏释,另一個(gè)變量也將受到更改的影響。這就是我們需要克隆這個(gè)數(shù)組的原因摸袁。
接著來(lái)看看一些關(guān)于拷貝和克隆數(shù)組的有趣方法和技巧钥顽。
### 技巧 1 - 使用`Array.slice`方法
const numbers = [1, 2, 3, 4, 5]const copy = numbers.slice()copy.push(6) // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy)console.log(numbers)// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 2 - 使用`Array.map`方法
const numbers = [1, 2, 3, 4, 5]const copy = numbers.map( num => num )copy.push(6) // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 3 - 使用`Array.from `方法
const numbers = [1, 2, 3, 4, 5];const copy = Array.from(new Set(numbers));copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 4 - 使用展開(kāi)操作符
const numbers = [1, 2, 3, 4, 5];const copy = [...numbers];copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出 // [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 5 - 使用 `Array.of` 方法和展開(kāi)操作符
const numbers = [1, 2, 3, 4, 5];const copy = Array.of(...numbers);copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出 // [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
`Array.of()` 方法創(chuàng)建一個(gè)具有可變數(shù)量參數(shù)的新數(shù)組實(shí)例,而不考慮參數(shù)的數(shù)量或類(lèi)型靠汁。`Array.of()` 和 `Array` 構(gòu)造函數(shù)之間的區(qū)別在于處理整數(shù)參數(shù):`Array.of(7`) 創(chuàng)建一個(gè)具有**單個(gè)元素 7 的數(shù)組**蜂大,而 `Array(7)` 創(chuàng)建一個(gè)長(zhǎng)度為`7`的空數(shù)組(注意:這是指一個(gè)有`7個(gè)`空位(empty)的數(shù)組,而不是由`7`個(gè)`undefined`組成的數(shù)組)蝶怔。
Array.of(7); // [7] Array.of(1, 2, 3); // [1, 2, 3]Array(7); // [ , , , , , , ]Array(1, 2, 3); // [1, 2, 3]
### 技巧 6 - 使用 Array 構(gòu)造函數(shù)和展開(kāi)操作符
const numbers = [1, 2, 3, 4, 5];const copy = new Array(...numbers);copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出 // [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 7 - 使用解構(gòu)
const numbers = [1, 2, 3, 4, 5];const [...copy] = numbers;copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 8 - 使用 Array.concat 方法
const numbers = [1, 2, 3, 4, 5];const copy = numbers.concat();copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 9 - 使用 `Array.push` 方法和展開(kāi)操作符
const numbers = [1, 2, 3, 4, 5];let copy = [];copy.push(...numbers);copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 10 - 使用 `Array.unshift ` 方法和展開(kāi)操作符
const numbers = [1, 2, 3, 4, 5];let copy = [];copy.unshift(...numbers);copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 11 - 使用 `Array.forEach` 方法和展開(kāi)操作符
const numbers = [1, 2, 3, 4, 5];let copy = [];numbers.forEach((value) => copy.push(value));copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 12 - 使用 `for` 循環(huán)
const numbers = [1, 2, 3, 4, 5];let copy = [];for (let i = 0; i < numbers.length; i++) { copy.push(numbers[i]);}copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 13 - 使用 `Array.reduce` 方法
> 這個(gè)做法是可行奶浦,但比較多余,少用
const numbers = [1, 2, 3, 4, 5];const copy = numbers.reduce((acc, x) => { acc.push(x); return acc; }, []);copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
### 技巧 14 - 使用古老的 `apply` 方法
const numbers = [1, 2, 3, 4, 5];
let copy = [];Array.prototype.push.apply(copy, numbers);copy.push(6); // 添加新項(xiàng)以證明不會(huì)修改原始數(shù)組console.log(copy);console.log(numbers);// 輸出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]
**代碼部署后可能存在的BUG沒(méi)法實(shí)時(shí)知道添谊,事后為了解決這些BUG财喳,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug斩狱。**
原文:https://twitter.com/protic_milos
### 總結(jié)
**請(qǐng)注意**耳高,上面這些方法執(zhí)行的是淺拷貝,就是數(shù)組是元素是對(duì)象的時(shí)候所踊,咱們更改對(duì)象的值泌枪,另一個(gè)也會(huì)跟著變,就能**技巧4**來(lái)說(shuō)秕岛,如果咱們的數(shù)組元素是對(duì)象碌燕,如下所示:
const authors = [ { name: '前端小智', age: 25 }, { name: '王大冶', age: 30 }, ]const copy = [...authors ]copy[0].name = '被更改過(guò)的前端小智'console.log(copy)console.log(authors)
輸出


[閱讀原文](https://mp.weixin.qq.com/s?__biz=MzIwMDYyOTE1NA==&mid=2650235209&idx=1&sn=15b50e7be88f519894e5de6b84193bc0&chksm=8ef98f84b98e06921ab76a14e247ce2de5b58e5ecf7747816027840da91e0b38e7d80cfeba51&scene=0&xtrack=1&key=d6a080855538065e07da9c82810d3c8d3e6df0670621cf04fbfa937a23c71a8d17487cc1d56299da9cbdad48c5d967a62caaa9c8226ca999c865209984ad6ed37e88a39b966aee8fdba8b13ad751e479&ascene=1&uin=MjI2MDA3ODQyMw%3D%3D&devicetype=Windows+7&version=62060834&lang=zh_CN&pass_ticket=csPtwbpfBJsy5STsuFnc%2FYJNBhJY53roQGyuZ3k1GqhrFnaRV1nYVGlJZHH8sC3Y&winzoom=1##)