之前在写一个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. Assets.xcassets的使用

    先介绍下Asset Catalog,Asset Catalog是Xcode5引入的一个新的图片管理方式,有几个好处: 1.自动管理图片,如@1x,@2x图片,使用的时候使用Asset 名字即可 2.管 ...

  2. spring容器启动完成后加载自定义逻辑

    业务需求中,可能会有一些逻辑需要在应用启动完成后,例如字典缓存,资源池初始化等等,代码如下 public class InitApplication implements ApplicationCon ...

  3. 007-zabbix Server 4.0 监控TCP的12种状态

    大家对TCP三次握手比较熟悉了,都知道当发生DOSS攻击时,客户端发送SYN给服务端后,服务端响应SYN+ACK,此时客户端就不回应服务端ACK啦(如果正常建立三次握手客户端会回应ACK,表示三次握手 ...

  4. Java中通过相对路径来定位文件

    通常我们定位文件都是通过绝对路径进行定位,比如“F:/Java/bin/test/test.java”,这样的缺点就是,一旦项目文件移动,这些路径就完全失效. 所以,下面我们来介绍一种通过相对路径来定 ...

  5. java面试(集合类)03

    1.Collection 和 Collections 有什么区别? Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所有集合都是它的子类,比如 List.Set 等 ...

  6. MYSQL explain详解[转载]

    explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 虽然这篇文章我写的很长,但看起来真的不会困啊,真的都是干货啊!!!! 先解析 ...

  7. openssl x.509证书

    openssl x.509证书 openssl x.509证书 ngnix 支持

  8. netty学习第5章 netty整合websocket

    学习netty之后,可能都有一个疑问,就是如何选择一个编码.解码器,在netty中的编解码可是和json这种编解码是不一样的,netty的编解码器主要是解决TCP粘包.拆包的问题.netty中有许多自 ...

  9. @Autowired与@Resource的区别(转载)

    原文地址:http://bhdweb.iteye.com/blog/1663907 1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上.  ...

  10. Python 3标准库第四章

    第四章日期和时间-----------------    不同于int.float和str,Python没有包含对应日期和时间的原生类型,不过提供了3个相应的模块,可以采用多种表示来管理日期和时间值. ...