JS中数组的拷贝方法
之前在写一个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.stringify和JSON.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中数组的拷贝方法的更多相关文章
- js中数组的定义方法及注意事项(转)
1.数组的创建 var name= new Array(); //创建一个数组 name[0]="zhangsan"; //给数组赋值 name[1]="lisi&q ...
- 前端学习笔记系列一:9 js中数组的拷贝
拷贝分为浅拷贝和深拷贝,在JavaScript中能够实现这两种拷贝的方式也是多种多样.以下是一维数组实现深拷贝和浅拷贝的各种方式. 一.浅拷贝 1.赋值 赋值是最直接的一种浅拷贝. let arr3 ...
- js中数组的检测方法
在js中可以使用Object.prototype.toString.call()的来检测一个对象是否为一个数组 //检测数组 var a = [1, 2]; console.log(typeof a) ...
- JS中数组的迭代方法和归并方法
昨天总结的JavaScript中的数组Array方法 数组的迭代方法 ES5中为数组定义了5个迭代方法.每个方法都要接收两个参数:要在每一项上面运行的函数和(可选的)运行该函数的作用域对象---影响t ...
- JS中数组和字符串方法的简单整理
一.数组: 数组的基本方法: 1.增:arr.unshift() /push() 前增/后增 2.删:arr.shift() /pop ...
- JS中数组重排序方法
在数组中有两个可以用来直接排序的方法,分别是reverse()和sort().下面通过本文给大家详细介绍,对js数组重排序相关知识感兴趣的朋友一起看看吧 1.数组中已存在两个可直接用来重排序的方法:r ...
- js中数组去重的方法
在实际工作或面试中,我们经常会遇到"数组去重"问题,接下来就是使用js实现的数组去重的多种方法: 1.借助ES6提供的Set结构 var arr = [1,1,2,2,3,3,4, ...
- js中数组的map()方法
map()方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值 map()方法按照原是数组顺序以此处理元素 注意:map()不会对空数组进行检测 :不会改变原始的数组 实例: var nu ...
- JS中数组的创建方法
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
随机推荐
- HTTP,FTP异常码大全【转载】
HTTP 400 - 请求无效HTTP 401.1 - 未授权:登录失败HTTP 401.2 - 未授权:服务器配置问题导致登录失败HTTP 401.3 - ACL 禁止访问资源HTTP 401.4 ...
- html 常用小技巧
style = "cursor:pointer;" 变小手 a{ text-decoration:none; } 或者把这个属性分别加到a标签下, a:link{ text-dec ...
- HMC版本支持
Target Version Upgrade From Upgrade Instructions Updates Date Available End of Service Models supp ...
- 【转】Linux iptables 详解
转自:https://www.cnblogs.com/qwertwwwe/p/9452370.html 最近搭一个框架需要用到iptables做映射,学习了下iptables的原理,总结下方便以后查~ ...
- Python excel读写
# coding=utf-8 print "----------------分割线 xlrd--------------------" import xlrd #打开一个wordb ...
- java医院交费机
1.读卡器 钱币识别器 身份证识别等 2.与银行交互 socket客户端 发送 10001 返回解析 查询余额 密码发送 3.界面展示freemaker ftl文件展示 4.hql语句 5.webse ...
- LaunchScreen 设置启动图片出现的问题
更换启动图片的时候出现了一系列的小问题,让人头疼,怀疑人生. 1.更换了图片,显示还是老的图片! -->重启手机,clean Xcode 2.设置布局的时候,请务必要这么布局,很完美! 如果你 ...
- 深入理解JAVA虚拟机 晚期(运行期)优化(转载)
这一章节的内容实用性不强 所以不再手打笔记 转载了一篇 原文地址是http://blog.csdn.net/qq_27350929/article/details/54837595 在部分的商用虚拟机 ...
- NJU 操作系统实验三
实验描述: 代码实现: 链接:https://pan.baidu.com/s/1so3-XsvWBY9ZDbINob6qCw 提取码:8hhe
- springboot 集成apollo,根据不同环境加载配置