网站首页 > 基础教程 正文
问题
写代码时需要拷贝一个内容会变化的数组,使用了=赋值,slice(),concat()方法都不行,修改了原数组后拷贝数组也变了,原因是这个数组内容是object,而object是引用类型,需要使用深拷贝,最后使用var newArr = JSON.parse(JSON.stringify(arr));解决
浅拷贝&深拷贝
- 浅拷贝:如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,无论对新旧数组的哪一个进行了修改,两者都会发生变化。
- 深拷贝:完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。
var arr = [{name: 'wens'},{age: '26'}]; //原数组
var newArr1 = arr; //浅拷贝
var newArr2 = arr.slice(); //浅拷贝
var newArr3 = arr.concat(); //浅拷贝
var newArr4 = JSON.parse(JSON.stringify(arr)); //深拷贝
arr[0].name = 'leon';
arr[1].age = '27';
console.log(arr);
console.log(newArr1);
console.log(newArr2);
console.log(newArr3);
console.log(newArr4);
运行结果:
浅拷贝
1.使用=直接赋值
var newArr = arr;
缺点:由于数组是引用类型,修改了arr或者newArr中的一个会影响全部
2.使用slice()
var newArr = arr.slice();
3.使用concat()
var newArr = arr.concat();
slice()和concat()缺点:当数组内部属性值为引用对象时,使用slice和concat对对象数组的拷贝,整个拷贝还是浅拷贝,拷贝之后数组各个值的指针还是指向相同的存储地址。简单来说就是:
数组中的值如果是引用类型,对其进行增删改,会影响用slice复制的数组,
但是如果数组中的值是基本类型,就不会影响
深拷贝
1.使用JSON.stringify和JSON.parse
不仅可拷贝数组还能拷贝对象(但不能拷贝函数)
var newArr = JSON.parse(JSON.stringify(arr));
缺点:JSON.stringify()有一些局限,比如对于RegExp类型和Function类型则无法完全满足,而且不支持有循环引用的对象。
2.深拷贝的一个通用方法
实现思路:拷贝的时候判断属性值的类型,如果是对象,继续递归调用深拷贝函数
var deepCopy = function(obj) {
// 只拷贝对象
if (typeof obj !== 'object') return;
// 根据obj的类型判断是新建一个数组还是一个对象
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
// 遍历obj,并且判断是obj的属性才拷贝
if (obj.hasOwnProperty(key)) {
// 判断属性值的类型,如果是对象递归调用深拷贝
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}
- 上一篇: 一大波开源小抄来袭 开源小说软件下载
- 下一篇: 前端笔记-js浅拷贝和深拷贝 js实现浅拷贝和深拷贝
猜你喜欢
- 2024-12-22 Vue进阶(十三):MOCK vue mock.js教程
- 2024-12-22 10 个超棒的 JavaScript 简写技巧
- 2024-12-22 js常用数组API方法汇总 js数组的用法
- 2024-12-22 js中常见的几种排序算法 js常用排序
- 2024-12-22 一文掌握:掌握 JavaScript 中的内存生命周期。
- 2024-12-22 前端笔记-js浅拷贝和深拷贝 js实现浅拷贝和深拷贝
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)