JavaScript深拷贝和浅拷贝详解
一. 为什么要用深拷贝和浅拷贝
var obj = { a: 1, b: 1, c: 2 }
var newObj = obj // newObj = { a: 1, b: 1, c: 2 }
obj.a = 5
// obj = { a: 5, b: 1, c: 2 }
// newObj = { a: 5, b: 1, c: 2 }
var arr = [1, 2, 3, 4, 5]
var newArr = arr // newArr = [1, 2, 3, 4, 5]
newArr[2] = 9
// arr = [1, 2, 9, 4, 5]
// newArr = [1, 2, 9, 4, 5]
当我们用等号直接给引用数据类型赋值的时候,其实就是复制了一个指针,指向该变量所存的内存地址,所以当一个变量改变时会影响到另一个变量,这时,我们用拷贝的方法进行赋值就不会影响了。
二. 什么是深拷贝和浅拷贝
深拷贝:拷贝对象所有层级,相当于创建一个和原对象一模一样的新对象
浅拷贝:只拷贝对象第一层级,深层级的内容和原对象共同使用,当一个对象发生改变时,两个对象同步改变
三. 浅拷贝的实现
方法一:for循环
var obj = {
name: 'wang',
age: 18,
happy: {
exercise: 'ball'
}
}
var newObj = {}
for (var key in obj) {
newObj[key] = obj[key]
}
方法二:Object.assign
var obj = {
name: 'wang',
age: 18,
happy: {
exercise: 'ball'
}
}
var newObj = Object.assign({}, obj)
obj.name = 'xiao'
// obj.name = 'xiao'
// newObj.name = 'wang'
newObj.happy.exercise = 'book'
// obj.happy.exercise = 'book'
// obj.happy.exercise = 'book'
**两个对象第一层级的内容拷贝成功,一方改变并不会影响另一方,但是happy内的值是公用的,一方改变另一方也会随着改变**
四. 深拷贝的实现
方法一:JSON.parse() JSON.stringify() // 缺点:无法实现对象中的方法属性,function和undefined的拷贝
var obj = {
name: 'wang',
age: 18,
happy: {
exercise: 'ball',
eat: function () {
return 'apple'
},
sleep: undefined
}
}
var newObj = JSON.parse(JSON.stringify(obj))
// newObj = {
// name: 'wang',
// age: 18,
// happy: {
// exercise: 'ball'
// }
// }
newObj.happy.exercise = 'book'
// obj.happy.exercise = 'ball'
// newObj.happy.exercise = 'book'
方法二:递归
var obj = {
name: 'wang',
age: 18,
happy: {
exercise: 'ball',
eat: function () {
return 'apple'
},
sleep: undefined
},
strong: [180, 70]
}
function deepcopy (obj) {
let newObj = {}
for (var key in obj) {
if (obj[key] instanceof Object) {
newObj[key] = deepcopy(obj[key])
}else {
newObj[key] = obj[key]
}
}
}
deepcopy(obj)