浅拷贝与深拷贝
浅拷贝
浅拷贝就是创建一个新的对象,用来接受要复制和引用的值,如果要拷贝的值为数字,则进行赋值运算,如果是引用对象,则将拷贝的对象路径分享给新的对象
而使用对象路径的话,其实就是引用了它得属性,值会跟着拷贝对象改变,这就是浅拷贝。
浅拷贝的方法:
1.Object.assign()
这个方法是es6中object的方法,使用简单
Object.assign()
方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。然后返回目标对象。
如
可以看到app将app1里面的值加到app里面了,app1为拷贝对象,app为拷贝到的值
注意:
使用 object.assign 方法有几点需要注意:
它不会拷贝对象的继承属性;
它不会拷贝对象的不可枚举的属性;
可以拷贝 Symbol 类型的属性。
2.扩展运算符
扩展运算符的语法为:let cloneObj = { ...obj };
/* 对象的拷贝 */
let obj = {a:1,b:{c:1}}
let obj2 = {...obj}
obj.a = 2
console.log(obj) //{a:2,b:{c:1}} console.log(obj2); //{a:1,b:{c:1}}
obj.b.c = 2
console.log(obj) //{a:2,b:{c:2}} console.log(obj2); //{a:1,b:{c:2}}
/* 数组的拷贝 */
let arr = [1, 2, 3];
let newArr = [...arr]; //跟arr.slice()是一样的效果
扩展运算符 和 object.assign 有同样的缺陷,也就是实现的浅拷贝的功能差不多,但是如果属性都是基本类型的值,使用扩展运算符进行浅拷贝会更加方便。
3.concat
还可以使用concat进行数组浅拷贝,注意concat只能用于数组的拷贝,比较有1局限性
使用方法如上。
4.slice数组截取
slice是一个用于数组截取的方法,slice(begin,end),这个方法与concat方法一样,只能用于数组
深拷贝
学习了浅拷贝了之后发现,浅拷贝只能拷贝对象中的值,和一层属性,如果要拷贝完全的内容就要用到深拷贝
1.Json.stringfy()
这个方法就是将一个对象转为JSON数据,在转换为string数据,适用方法如:
但是使用 JSON.stringfy 实现深拷贝还是有一些地方值得注意,我总结下来主要有这几点:
-
拷贝的对象的值中如果有函数、undefined、symbol 这几种类型,经过 JSON.stringify 序列化之后的字符串中这个键值对会消失;
-
拷贝 Date 引用类型会变成字符串;
-
无法拷贝不可枚举的属性;
-
无法拷贝对象的原型链;
-
拷贝 RegExp 引用类型会变成空对象;
-
对象中含有 NaN、Infinity 以及 -Infinity,JSON 序列化的结果会变成 null;
-
无法拷贝对象的循环应用,即对象成环 (obj[key] = obj)。