深克隆这个问题一般在考察js基础的时候问的频率还是比较大的.那么什么是深克隆什么是浅克隆呢,怎么实现一个深克隆呢?
1.简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。 2.对于简单数据类型来说他的值是直接存储在栈内存的,而对于引用数据来说,他在栈内存中只是存储了一个引用,真正的数据是存储在堆内存的.
首先 实现一个浅克隆的方法很简单
//原对象
let obj = { a:1,b:2,c:{d:1} }
//1.通过直接赋值
let obj1 = obj
console.log(obj1===obj)//true
//2.通过es6的拓展运算符展开到新的对象内也是浅克隆
let obj2 = {...obj}
console.log(obj2===obj)//false 第一层地址被改变了
//但是我们修改一下obj.c.d=2,我们会发现obj2.c.d也被修改了 第二层依旧是浅克隆
那么我们的项目需求是实现一个深拷贝,应该怎么做呢?
1.比较简单的一个方法就是通过JSON转化一下
let obj3 = JSON.parse(JSON.stringify(obj))
确实可以实现,对于一个不太复杂的数据结构来说这个方法还是很简便的,但是JSON无法克隆值为函数,Date,正则的数据
//这个就需要使用递归来获取深拷贝的结果
let deepClone = (o) => {
// 判断o的类型
if (o == null || typeof o !== 'object') return o
// 判断o是不是正则表达式
if (o instanceof RegExp) return new RegExp(o);
// 判断o是不是Date
if (o instanceof Date) return new Date(o);
// 判断o是不是函数
if (o instanceof Function) return new Function(o);
let newObj = {};
for (let key in o) {
if (Object.hasOwnProperty.call(o, key)) {
newObj[key] = deepClone(o[key])
}
}
return newObj
}
补充
es6的Object.assign()属性实现的也是浅拷贝
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。也就是说,如果对象的属性值为简单类型(如string, number),通过Object.assign({},srcObj);得到的新对象为深拷贝;如果属性值为对象或其它引用类型,那对于这个对象而言其实是浅拷贝的。