js深拷贝、浅拷贝
2019-04-18 本文已影响0人
喵喵同学嘛
1. 基本介绍
在js中有两种数据类型,基本数据类型和引用数据类型,我们知道对其赋值操作的时候,对于基本数据类型,会直接把其值赋值给另外一个对象,但是对于引用数据类型,赋值的只是栈中的地址,其实指向的还是堆中的同一个对象,并不会创建新的对象。
那么如何进行拷贝呢
2. 浅拷贝
1、for in 循环
2、直接赋值
3、Object.assign(其实他的第一层是深拷贝,后面的是浅拷贝)
3. 深拷贝
1. JSON.parse(JSON.stringfy(obj))
这个会存在一些问题:
- 他无法实现对函数 、RegExp等特殊对象的克隆
- 会抛弃对象的constructor,所有的构造函数会指向Object
- 对象有循环引用,会报错
2. 自己手写一个
function DeepCopy(obj){
if(typeof obj!=='object'&& typeof obj !=='function') //基本类型
return obj
let newobj=Array.isArray(obj)?[]:{}
for(key in obj){
if(obj.hasOwnProperty(key)){ //是否是自己的属性,而不是原型对象上的属性
newobj[key]=typeof obj[key]==='object'?DeepCopy(obj[key]):obj[key]
}
}
return newobj
}
其实这个也是存在问题的,
- 对于正则表达式并不能复制
- 会抛弃对象的constructor,所有的构造函数会指向Object,如下图所示

要想真正的实现一个深拷贝,要进行对不同类型的判断作特殊处理
在实际项目中,还是要看具体情况来选择,如果属性的类型丰富,不确定,特别严格的话还是建议使用lodash库去实现