该文章主要用于自己在平时学习记录使用
浅拷贝与深拷贝
主要是针对js中引用类型的复制。在引用类型中,定义的变量相当于一个指针,指向了某个对象或数组的引用
浅拷贝
let obj = {a: 1, b: 1};
let newObj = obj;
newObj.a = 2;
console.log(obj.a); // 2
newObj
和obj
这两个变量都存储了指向对象的一个引用地址,实则共用一个对象,所以当改变newObj.a = 2
时,obj.a
也发生改变。这就是浅拷贝。
深拷贝
深拷贝就是让newObj.a
发送变化时,obj.a
不发生变化,newObj
和obj
相当于两个完全不同的对象。
深拷贝方法
- 使用最原始的方法,建立一个新的空对象或数组,遍历每个元素,将其放到新的对象或数组中,如果碰到元素也是引用类型的,则进行递归。
- 当进行深拷贝的元素数据为一个数组时,可以使用
slice()
或者concat()
或者ES6中的扩展运算符
(该方法也可用于一个对象)方法,但是该方法有个问题,当数组的元素也是一个引用类型时,则无法进行深层次的深拷贝。
let arr = [1, 2, [3, 4], {a: 1, b: 2}];
let newArr = arr.slice(); //newArr -> [1, 2, [3, 4], {a: 1, b: 2}]
newArr[0] = 'change';
console.log(arr, newArr);
可以发现:
newArr
通过slice()
方法复制了arr
,当改变newArr
第一层的元素时,arr
不受影响当改变深层的元素内容时,再来看一下效果:
可以发现:
newArr
和arr
的元素值都有变化经测试,
concat()
和ES6拓展运算符
与slice()
情况相同,有兴趣的童鞋可以自己试验下,童叟无欺!!!
-
最暴力、最直接的方式:
JSON.parse(JSON.stringify(obj))
,但是该方法也有一些缺陷:1.数组
数组元素有
undefined
或null
时:let arr = [undefined, 1, 2, 3, null]; console.log(JSON.parse(JSON.stringify(arr))); // [ null, 1, 2, 3, null ];
其中
undefined
被转为null
,null
依然为null
;2.对象
对象中有属性的
value
为undefined
或者null
时:let obj = {a: 1, b: undefined, c: null, d: 'null', e: 'undefined'}; console.log(JSON.parse(JSON.stringify(obj))); // { a: 1, c: null, d: 'null', e: 'undefined' }
其中
value
为undefined
的属性被剔除,其余情况不变。