JS基本类型的数据是直接存储在栈里
JS引用类型的数据是存储在堆里,栈里存的是引用地址
深、浅拷贝是针对引用类型的
赋值
let person = {
name: '张三',
hobby: ['跑步', '游泳', '打篮球']
}
let person1 = person
person1.name = '李四'
person1.hobby[0] = '学习'
console.log(person, person1)
此时person和person1的name和hobby[0]都改变。
赋值是将person对象在栈里保存的引用地址赋值给变量person1,它们指向的是同一个堆的数据。当堆的数据改变时,person和person1的数据都将改变。
浅拷贝
let person = {
name: '张三',
hobby: ['跑步', '游泳', '打篮球']
}
let person1 = this.shallowCopy(person)
person1.name = '李四'
person1.hobby[0] = '学习'
console.log(person, person1)
shallowCopy (obj) {
let target = {}
for (let i in obj) {
if (obj.hasOwnProperty(i)) target[i] = obj[i]
}
return target
}
此时person的name为“张三”,person1的name为“李四”,habby[0]都变为“学习”。
浅拷贝是将原对象person的堆数据和栈的引用类型都复制了一份,当堆里的基本数据类型改变时,不会影响原数据,而堆里的引用类型数据改变时,原数据也改变。
浅拷贝的实现方式
Object.assign()
concat
函数库lodash clone
深拷贝
let person = {
name: '张三',
hobby: ['跑步','游泳','打篮球']
}
let person1 = this.deepCopy(person)
person1.name = '李四'
person1.hobby[0] = '学习'
console.log(person, person1)
deepCopy (obj) {
let target = {}
if (obj === null) return
if (typeof obj !== 'object') return obj
for (let i in obj) {
if (obj.hasOwnProperty(i)) target[i] = this.deepCopy(obj[i])
}
return target
}
person1的name和hobby[0]都改变,person的不变。
深拷贝无论是普通类型还是引用类型,改变都不影响原数据。
深拷贝的实现方式
json.parse(json.stringfy(obj)),这个方法会导致原数据的function和data会丢失。
函数库lodash deepClone
$.extend
递归