之前在写一个vue的计算属性时,大概是这样:

computed: {
updateList () {
let newList = this.List
/*do something*/
return newList
},
}

  本想的是设置个中间变量newList,将它和原来的List相比做一些操作,最后返回这个newList,后来发现原List也改变了。才意识到这个newList只是个引用类型,改变了它原来的对象也会变。

  查资料的过程中,注意到了还有深拷贝浅拷贝的区别:

    浅拷贝是拷贝一层,深层次的对象级别的就只拷贝引用;

    深拷贝是拷贝多层,每一级别的数据都会拷贝出来。

一.Array的拷贝

1.浅拷贝

  如上,直接赋值的方式

2.深拷贝

(1)slice()方法

对于array对象的slice函数,返回一个数组的一段。(仍为数组)
arrayObj.slice(start, [end]) 参数:
arrayObj 必选项。一个 Array 对象。
start 必选项。arrayObj 中所指定的部分的开始元素是从零开始计算的下标。
end可选项。arrayObj 中所指定的部分的结束元素是从零开始计算的下标。 说明:
slice 方法返回一个 Array 对象,其中包含了 arrayObj 的指定部分。
slice 方法一直复制到 end 所指定的元素,但是不包括该元素。
如果 start 为负,将它作为 length + start处理,此处 length 为数组的长度。
如果 end 为负,就将它作为 length + end 处理,此处 length 为数组的长度。
如果省略 end ,那么 slice 方法将一直复制到 arrayObj 的结尾。
如果 end 出现在 start 之前,不复制任何元素到新数组中。

对于本例,let newList = this.List.slice()即可

(2)concat()方法

concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
语法:arrayObject.concat(arrayX,arrayX,......,arrayX)
说明:返回一个新的数组。该数组是通过把所有 arrayX 参数添加到 arrayObject 中生成的。如果要进行 concat() 操作的参数是数组,那么添加的是数组中的元素,而不是数组。

对于本例,let newList = this.List.concat()即可

但是,这两种方法都有局限性,如:

var arr1 = [{"name":"weifeng"},{"name":"boy"}];//原数组
var arr2 = [].concat(arr1);//拷贝数组
arr1[1].name="girl";
console.log(arr1);// [{"name":"weifeng"},{"name":"girl"}]
console.log(arr2);//[{"name":"weifeng"},{"name":"girl"}]
var a1=[["1","2","3"],"2","3"],a2;
a2=a1.slice(0);
a1[0][0]=0; //改变a1第一个元素中的第一个元素
console.log(a2[0][0]); //影响到了a2 var b1=[["1","2","3"],"2","3"],b2;
b2=b1.slice(0);
b1[0][0]=0; //改变a1第一个元素中的第一个元素
console.log(b2[0][0]); //影响到了a2

从上面两个例子可以看出,由于数组内部属性值为引用对象,因此使用slice和concat对对象数组的拷贝,整个拷贝还是浅拷贝,拷贝之后数组各个值的指针还是指向相同的存储地址。

因此,slice()和concat()这两个方法,仅适用于对不包含引用对象的一维数组的深拷贝

(3)使用JSON.stringifyJSON.parse实现深拷贝:

JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象

对于本例, let newList = JSON.parse(JSON.stringify(this.List))

JSON.stringify()有一些局限,比如不能拷贝function,详见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

(4)当然,如果是不那么复杂的数组,你可以声明一个新数组,自己写一个for循环拷贝过去。

JS中数组的拷贝方法的更多相关文章

  1. js中数组的定义方法及注意事项(转)

    1.数组的创建 var name= new Array(); //创建一个数组 name[0]="zhangsan";   //给数组赋值 name[1]="lisi&q ...

  2. 前端学习笔记系列一:9 js中数组的拷贝

    拷贝分为浅拷贝和深拷贝,在JavaScript中能够实现这两种拷贝的方式也是多种多样.以下是一维数组实现深拷贝和浅拷贝的各种方式. 一.浅拷贝 1.赋值 赋值是最直接的一种浅拷贝. let arr3 ...

  3. js中数组的检测方法

    在js中可以使用Object.prototype.toString.call()的来检测一个对象是否为一个数组 //检测数组 var a = [1, 2]; console.log(typeof a) ...

  4. JS中数组的迭代方法和归并方法

    昨天总结的JavaScript中的数组Array方法 数组的迭代方法 ES5中为数组定义了5个迭代方法.每个方法都要接收两个参数:要在每一项上面运行的函数和(可选的)运行该函数的作用域对象---影响t ...

  5. JS中数组和字符串方法的简单整理

    一.数组: 数组的基本方法:              1.增:arr.unshift() /push()    前增/后增                  2.删:arr.shift() /pop ...

  6. JS中数组重排序方法

    在数组中有两个可以用来直接排序的方法,分别是reverse()和sort().下面通过本文给大家详细介绍,对js数组重排序相关知识感兴趣的朋友一起看看吧 1.数组中已存在两个可直接用来重排序的方法:r ...

  7. js中数组去重的方法

    在实际工作或面试中,我们经常会遇到"数组去重"问题,接下来就是使用js实现的数组去重的多种方法: 1.借助ES6提供的Set结构 var arr = [1,1,2,2,3,3,4, ...

  8. js中数组的map()方法

    map()方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值 map()方法按照原是数组顺序以此处理元素 注意:map()不会对空数组进行检测 :不会改变原始的数组 实例: var nu ...

  9. JS中数组的创建方法

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

随机推荐

  1. iOS常用的数学函数

    1. 三角函数    double sin (double);正弦    double cos (double);余弦    double tan (double);正切    2 .反三角函数    ...

  2. DevExpress中的gridControl选择问题

    在Dev控件中,gridControl是最常用的一个了. //直接通过gridView获取当前行 dr=this.gridView1.GetDataRow(this.gridView1.Focused ...

  3. etl-p

    java excel 导入数据库 上传文件包  解压导入excel包 导入mysql

  4. Redux 聊聊

    前言 Redux 是 JavaScript 状态容器,提供可预测化的状态管理. 首先明确一点的就是: Redux并不是React必须的,也没有任何依赖,你可以很自由的将他应用到各种前端框架.jQuer ...

  5. 机器学习降维--SVD奇异值分解

    奇异值分解是有着很明显的物理意义,将一个比较复杂的矩阵用更小更简单的几个子矩阵的相乘来表示,这些小矩阵描述的是矩阵的重要的特性,让机器学会抽取重要的特征,SVD是一个重要的方法. 所以SVD不仅是一个 ...

  6. 【LuoguP4433】[COCI2009-2010#1] ALADIN(含类欧几里得算法推导)

    题目链接 题意简述 区间赋值模意义下等差数列,询问区间和 \(N\leq 10^9,Q\leq 10^5\) Sol 每次操作就是把操作区间\([L,R]\)中的数赋值成: \[(X-L+1)*A\ ...

  7. [每日一讲] Python系列:字典

    #! /usr/bin/python # coding:utf-8 """ DATA STRUCTURE Container: Mapping (Another cont ...

  8. grpc:gRPC Concepts

    本文介绍一些主要的gRPC概念. 服务定义 gRPC支持4种方法: 1.Unary RPCs where the client sends a single request to the server ...

  9. JUnit——单元测试

    写了个类,要给别人用,会不会有bug?怎么办?测试一下. JUnit可以测试JDBC.Servelet.Struts.Spring.Hibernate等等. 单元测试是开发人员的工作,测试人员负责测试 ...

  10. Python与CSV文件(CSV模块)

    Python与CSV文件(CSV模块)   1.CSV文件 CSV(逗号分隔值)格式是电子表格和数据库最常用的导入和导出格式.没有“CSV标准”,因此格式由许多读写的应用程序在操作上定义.缺乏标准意味 ...