浅拷贝和深拷贝
js内存结构
栈内存:保存的是基本数据类型 string number boolean undefined null
堆内存:保存的是引用数据类型 Object
在栈内存中: 一个变量保存对象 这个 变量实际上保存的是 地址值
这个地址值可以在堆内存中找到对应的一块空间,而这块空间就是用来存放对象中的数据
如图:
将obj的值 赋值 给 obj2也就是将obj保存的那个地址值赋值给obj2,导致obj和obj2都可以找到同一块内存空间.
操作的都是同一块内存空间,一边修改另一边也会变化
拷贝
浅拷贝
只拷贝一层,更深层的对象只拷贝地址值
let obj = {
name: '小明',
age: 2,
girlfriend: {
name: '小红'
}
}
function copy(obj){ // obj是要拷贝的对象(这里称为源对象)
let newObj = {} // 创建一个新对象
for(let i in obj){ // i 为obj的每一个属性名
newObj[i] = obj[i]
}
return newObj
}
let obj2 = copy(obj) // obj2浅拷贝obj
console.log(obj2.girlfriend === obj.girlfriend) // true
/*
为什么这两个对象的girlfriend还是相等的?
当for in 循环到 girlfriend 这项时,发生如下情况:
newObj['girlfriend'] = obj['girlfriend']
这时obj['girlfriend'] 保存的是一个地址值,将这个地址值赋值给了newObj['girlfriend']
所以这里出现相等情况 这也就是浅拷贝
如果obj.girlfriend.name = '小花' , 那么 newObj.girlfriend.name 也为 '小花'
他们两个的 girlfriend 指向同一块内存空间
*/
深拷贝
拷贝多层,每层数据都会拷贝(回用到递归)
let obj = {
name: '小明',
age: 2,
girlfriend: {
name: '小红'
}
}
function deepCopy(obj){
let newObj = {}
for(let i in obj){
if(obj[i] instanceof Object){ // 如果该项为引用数据类型(对象)
newObj[i] = deepCopy(obj[i]) // 递归再调用本身拷贝这个引用数据,会返回一个新对象
}else{ // 基本数据类型
newObj[i] = obj[i]
}
}
return newObj
}
let obj2 = deepCopy(obj) // obj2深拷贝obj
console.log(obj2.girlfriend === obj.girlfriend) // false
/*
分析:
当for in 循环到 girlfriend 这项时发生如下情况:
obj[i] == girlfriend:{xxxxx} 是个对象
obj[i] instanceof Object // true进入执行代码块
执行代码块:
newObj[i] = deepCopy(obj[i])
deepCopy(obj[i]) 会返回一个新的对象
这个新的对象里面包含了obj[i]也就是obj.girlfriend里的属性
完成了深层拷贝
这就是深拷贝
*/
还有一种比较简单的实现深拷贝的方法:
// 利用JSON(javascript对象表示法)
let obj2 = JSON.parse(JSON.stringify(obj))
// 先把源对象转换成JSON格式字符串,再解析这个JSON字符串.用一个变量保存
本文来自博客园,作者:ycccc丶,转载请注明原文链接:https://www.cnblogs.com/imycc/p/16506543.html