目录
一:浅拷贝
二:深拷贝的底层原理
三:给出深拷贝和浅拷贝的语法糖和区别:
一:浅拷贝
底层原理,创建一个新的对象,利用遍历的方式把原来对象的键对值给新对象,代码如下
let obj = {
name: "张三",
sex: "男",
age: 18,
testArr: [1, 2, 3],
msg: {
adress: "中国山东蓝翔计数学院",
hobbit: "吃小火锅"
},
testFunction: function() {
console.log("给你两拳")
}
}
//创建一个新对象
let copyObj = {}
//遍历原有对象并把它的键对值复制给新对象
for (let k in obj) {
copyObj[k] = obj[k]
}
console.log(copyObj )
console.log(copyObj.msg===obj.msg)
最后我们来检验一下代码执行结果:
可以看到我们生成了一个新的对象,内容跟原有对象一样。但是当对象里存在复杂数据类型的时候,由于js复杂数据类型的存储机制,实际上新生成的对象和原来对象属性名里存储的是同一个地址,这会导致我们修改了其中一个的时候另外一个也会改变,我们对这句话做出检验。
copyObj.msg.name = "李四"
console.log(copyObj.msg.name, obj.msg.name)
再次来看代码执行结果
我们只修改了一个对象储存的信息,另外一个对象里存储的信息也被改变了,这不符合我们的使用习惯,所以有了深拷贝。
二:深拷贝的底层原理1.我们构造一个遍历对象用的函数,它对对象属性存的数据类型进行判断。
2.如果该数据类型是简单数据类型,就通过键对值复制的方法储存到新对象里
3.如果该数据类型是复杂数据类型,就创建一个值为空的对应的复杂数据类型数据,调用定义好的函数对这一项单独进行遍历,把键对值得集合保存在这个空的数据里,整体储存在上一层对象里。
代码如下:
function deepCopy(oldObj, newObj) {
for (let k in oldObj) {
if (oldObj[k] instanceof Object == false) {
newObj[k] = oldObj[k]
} else if (oldObj[k] instanceof Array) {
//对数组进行深拷贝
newObj[k] = []
oldObj[k].forEach(function(value) {
newObj[k].push(value)
})
} else if (oldObj[k] instanceof Object && oldObj[k] instanceofFunction== false) {
//对对象里的对象进行深拷贝
newObj[k] = {}
deepCopy(oldObj[k], newObj[k])
}
}
}
let newObj = {}
deepCopy(obj, newObj)
//打印函数的执行结果,并对对象里储存的复杂数据类型是否相等做出判断
console.log(newObj)
console.log(obj.msg === newObj.msg)
代码执行结果如下
可以看到深拷贝出来的复杂数据类型的地址是不同的,当我们改变了其中一个对象的信息的时候,另外一个对象的信息不会改变。
下面做出验证: 执行如下代码:
newObj.msg.adress = "上海市"
console.log(newObj.msg.adress, obj.msg.adress)
结果如下:
4.方法的访问可以通过call()或者bind()改变原有方法的this指向来进行访问
三:给出深拷贝和浅拷贝的语法糖和区别:
方法 | 类型 | 个人建议 |
Object.assign() | 浅拷贝 | 无 |
通过 JSON.parse(JSON.stringify(oldObj)) | 简化版的深拷贝 | 复杂数据类型在转化的过程中会造成信息丢失。 |
自定义函数进行迭代拷贝 | 深拷贝 | 推荐 |
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)