JavaScript中的數(shù)據(jù)類型主要分為原始數(shù)據(jù)類型(Number,String,Boolean,Null,Undefined,Symbol)和引用類型(Object)。深拷貝和淺拷貝主要是針對(duì)引用類型的,即在拷貝一個(gè)對(duì)象時(shí),對(duì)于對(duì)象中屬性值是對(duì)象的情況,淺拷貝復(fù)制的是對(duì)象的引用,深拷貝會(huì)復(fù)制對(duì)象的值。舉個(gè)例子說,假設(shè)B復(fù)制了A,如果B改變了,A跟著改變,這就是淺拷貝,如果B改變了而A不改變,此時(shí)就是深拷貝。
- 淺拷貝可以用
Object.assign()實(shí)現(xiàn),也可以用...擴(kuò)展運(yùn)算符實(shí)現(xiàn)
Object.assign()方法用于將所有可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象復(fù)制到目標(biāo)對(duì)象。它將返回目標(biāo)對(duì)象。
let temp = {
name:'temp',
obj:{
msg:'hello'
},
fn:function(){
console.log('hello')
}
}
let shallowCopy = Object.assign({},temp)
temp.obj.msg='hi'
console.log(shallowCopy.obj.msg)//hi
- 深拷貝的實(shí)現(xiàn)方法主要有兩種:JSON和遞歸
- JSON
先把對(duì)象序列化成JSON字符串,然后再把字符串解析成對(duì)象,這種方法只適合處理屬性值是對(duì)象或者數(shù)組的情況,對(duì)于函數(shù)會(huì)失真。還有,會(huì)丟失constructor,不管原先是什么,都會(huì)成為Object。
let temp = {
name:'temp',
obj:{
msg:'hello'
},
fn:function(){
console.log('hello')
}
}
let deepCopy1 = JSON.parse(JSON.stringify(temp))
temp.obj.msg='hi'
console.log(deepCopy1.obj.msg,deepCopy1.fn)//hello undefined
- 遞歸,for...in...循環(huán)遍歷屬性
function deepClone(obj) {
//判斷是否是數(shù)組
let result = Array.isArray(obj) ? [] : {}
for (let key in obj) {
//判斷是否是自身的屬性
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
//如果屬性值是對(duì)象,對(duì)這個(gè)對(duì)象深拷貝
result[key] = deepClone(obj[key])
} else {
//如果屬性值類型不是object,直接復(fù)制
result[key] = obj[key]
}
}
}
return result
}
let temp = {
name:'temp',
obj:{
msg:'hello'
},
fn:function(){
console.log('hello')
}
}
let deepCopy2 = deepClone(temp)
temp.obj.msg='hi'
console.log(deepCopy2.obj.msg) //hello
deepCopy2.fn() //hello