js拷贝

作者: lu2294 | 来源:发表于2019-11-13 14:20 被阅读0次
## 14 个拷贝数组的 JS 技巧

[100素材网](javascript:void(0);) *今天*

以下文章来源于大迁世界 ,作者前端小智

 [![大迁世界](https://img.haomeiwen.com/i9195867/abc228ac9568dd32?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 

**大迁世界**

我要先坚持分享20年,大家来一起见证吧。](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#) 

**为了保证的可读性,本文采用意译而非直译。**

数组拷贝经常被误解,但这并不是因为拷贝过程本身,而是因为缺乏对 JS 如何处理数组及其元素的理解。JS 中的数组是可变的,这说明在创建数组之后还可以修改数组的内容。

这意味着要拷贝一个数组,咱们不能简单地将旧数组分配给一个新变量,它也是一个数组。如果这样做,它们将共享相同的引用,并且在更改一个变量之后,另一个变量也将受到更改的影响。这就是我们需要克隆这个数组的原因。

接着来看看一些关于拷贝和克隆数组的有趣方法和技巧。

### 技巧 1 - 使用`Array.slice`方法

const numbers = [1, 2, 3, 4, 5]const copy = numbers.slice()copy.push(6) // 添加新项以证明不会修改原始数组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) // 添加新项以证明不会修改原始数组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); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


### 技巧 4 - 使用展开操作符

const numbers = [1, 2, 3, 4, 5];const copy = [...numbers];copy.push(6); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出 // [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


### 技巧 5 - 使用 `Array.of` 方法和展开操作符

const numbers = [1, 2, 3, 4, 5];const copy = Array.of(...numbers);copy.push(6); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出 // [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


`Array.of()` 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。`Array.of()` 和 `Array` 构造函数之间的区别在于处理整数参数:`Array.of(7`) 创建一个具有**单个元素 7 的数组**,而 `Array(7)` 创建一个长度为`7`的空数组(注意:这是指一个有`7个`空位(empty)的数组,而不是由`7`个`undefined`组成的数组)。

Array.of(7); // [7] Array.of(1, 2, 3); // [1, 2, 3]Array(7); // [ , , , , , , ]Array(1, 2, 3); // [1, 2, 3]


### 技巧 6 - 使用 Array 构造函数和展开操作符

const numbers = [1, 2, 3, 4, 5];const copy = new Array(...numbers);copy.push(6); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出 // [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


### 技巧 7 - 使用解构

const numbers = [1, 2, 3, 4, 5];const [...copy] = numbers;copy.push(6); // 添加新项以证明不会修改原始数组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); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


### 技巧 9 - 使用 `Array.push` 方法和展开操作符

const numbers = [1, 2, 3, 4, 5];let copy = [];copy.push(...numbers);copy.push(6); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


### 技巧 10 - 使用 `Array.unshift ` 方法和展开操作符

const numbers = [1, 2, 3, 4, 5];let copy = [];copy.unshift(...numbers);copy.push(6); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


### 技巧 11 - 使用 `Array.forEach` 方法和展开操作符

const numbers = [1, 2, 3, 4, 5];let copy = [];numbers.forEach((value) => copy.push(value));copy.push(6); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


### 技巧 12 - 使用 `for` 循环

const numbers = [1, 2, 3, 4, 5];let copy = [];for (let i = 0; i < numbers.length; i++) { copy.push(numbers[i]);}copy.push(6); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


### 技巧 13 - 使用 `Array.reduce` 方法

> 这个做法是可行,但比较多余,少用

const numbers = [1, 2, 3, 4, 5];const copy = numbers.reduce((acc, x) => { acc.push(x); return acc; }, []);copy.push(6); // 添加新项以证明不会修改原始数组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); // 添加新项以证明不会修改原始数组console.log(copy);console.log(numbers);// 输出// [1, 2, 3, 4, 5, 6]// [1, 2, 3, 4, 5]


**代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。**

原文:https://twitter.com/protic_milos

### 总结

**请注意**,上面这些方法执行的是浅拷贝,就是数组是元素是对象的时候,咱们更改对象的值,另一个也会跟着变,就能**技巧4**来说,如果咱们的数组元素是对象,如下所示:

const authors = [ { name: '前端小智', age: 25 }, { name: '王大冶', age: 30 }, ]const copy = [...authors ]copy[0].name = '被更改过的前端小智'console.log(copy)console.log(authors)


输出

![image.gif](https://img.haomeiwen.com/i9195867/1d02c2383e95d696.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 

![image.gif](https://img.haomeiwen.com/i9195867/bcaeaadc78b5a27d.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

[阅读原文](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##)

相关文章

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • JS实现深拷贝、instanceof、判断是否为数组

    JS深拷贝 JS中拷贝对象可以按照拷贝的程度可以分为浅拷贝和深拷贝,有些时候我们需要拷贝之后的对象和拷贝之前的对象...

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

  • JS工具-类型判断和深拷贝

    1. js深拷贝 js深拷贝简单对象的拷贝可以用JSON.stringify() 和 JSON.parse() 实...

  • JavaScript对象的拷贝

    本文主要介绍js对象的拷贝,包括浅拷贝和深拷贝,侧重实际方式,简单介绍概念。 一、js数据类型 js数据有不同的划...

  • JS文集的目录

    js基础心法 深浅拷贝(递归)深浅拷贝(首层浅拷贝) js 数据处理 数组对象查找的常见操作数组对象去重的常见操作...

  • 浅拷贝和深拷贝

    本文参考:JavaScript中的浅拷贝和深拷贝js 深拷贝 vs 浅拷贝深入剖析 JavaScript 的深复制...

  • 重新认识js复杂类型数据的引用和深浅拷贝

    js 基本概念———— 数据类型 js 深浅拷贝之概念 代码实现 —— 数组和对象的j浅拷贝 代码实现 —— 数组...

  • JS深拷贝

    深拷贝,拷贝引用对象的引用对地址和栈。先编辑deepClone.js文件 在html中引入deepClone.js...

  • js的深拷贝与浅拷贝及实现方法

    前提 理解深拷贝和浅拷贝之前,我们先理解下js变量的存储方式。 js变量分为基础类型(Undefined、Null...

网友评论

      本文标题:js拷贝

      本文链接:https://www.haomeiwen.com/subject/habhictx.html