let a =
let b = a
a.age = 2
console.log(b.age) // 2
首先可以通過object.assign
來解決這個問題,很多人認為這個函式是用來深拷貝的。其實並不是,object.assign
只會拷貝所有的屬性值到新的物件中,如果屬性值是物件的話,拷貝的是位址,所以並不是深拷貝。
let a =
let b = object.assign({}, a)
a.age = 2
console.log(b.age) // 1
另外我們還可以通過展開運算子...
來實現淺拷貝
let a =
let b =
a.age = 2
console.log(b.age) // 1
通常淺拷貝就能解決大部分問題了,但是當我們遇到如下情況就可能需要使用到深拷貝了
let a =
}let b =
a.jobs.first = 'native'
console.log(b.jobs.first) // native
淺拷貝只解決了第一層的問題,如果接下去的值中還有物件的話,那麼就又回到最開始的話題了,兩者享有相同的位址。要解決這個問題,我們就得使用深拷貝了。
這個問題通常可以通過json.parse(json.stringify(object))
來解決。
let a =
}let b = json.parse(json.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // fe
但是該方法也是有侷限性的:
let obj = ,
}obj.c = obj.b
obj.e = obj.a
obj.b.c = obj.c
obj.b.d = obj.b
obj.b.e = obj.b.c
let newobj = json.parse(json.stringify(obj))
console.log(newobj)
在遇到函式、undefined
或者symbol
的時候,該物件也不能正常的序列化
let a = ,
name: 'yck'
}let b = json.parse(json.stringify(a))
console.log(b) //
你會發現在上述情況中,該方法會忽略掉函式和undefined
。
但是在通常情況下,複雜資料都是可以序列化的,所以這個函式可以解決大部分問題。
如果你所需拷貝的物件含有內建型別並且不包含函式,可以使用messagechannel
function structuralclone(obj) = new messagechannel()
port2.onmessage = ev => resolve(ev.data)
port1.postmessage(obj)
})}var obj =
}obj.b.d = obj.b
// 注意該方法是非同步的
// 可以處理 undefined 和迴圈引用物件
const test = async () =>
test()
當然你可能想自己來實現乙個深拷貝,但是其實實現乙個深拷貝是很困難的,需要我們考慮好多種邊界情況,比如原型鏈如何處理、dom 如何處理等等,所以這裡我們實現的深拷貝只是簡易版,並且我其實更推薦使用 lodash 的深拷貝函式。
function deepclone(obj)
if (!isobject(obj))
let isarray = array.isarray(obj)
let newobj = isarray ? [...obj] :
reflect.ownkeys(newobj).foreach(key => )
return newobj
}let obj =
}let newobj = deepclone(obj)
newobj.b.c = 1
console.log(obj.b.c) // 2
// 定義乙個深拷貝函式 接收目標target引數
function deepclone(target)
// 判斷如果當前的值是null的話;直接賦值為null
} else if(target===null) else if(target.constructor===regexp)else ;
for (let i in target)
}// 如果不是物件的話,就是基本資料型別,那麼直接賦值
} else
// 返回最終結果
return result;
}
深淺拷貝以及深淺拷貝的方法
先考慮一種情況,對乙個已知物件進行拷貝,編譯系統會自動呼叫一種建構函式 拷貝建構函式,如果使用者未定義拷貝建構函式,則會呼叫預設拷貝建構函式。執行結果 呼叫一次建構函式,呼叫兩次析構函式,兩個物件的指標成員所指記憶體相同,name指標被分配一次記憶體,但是程式結束時該記憶體卻被釋放了兩次,會造成記憶...
拷貝和深淺拷貝
當list2為list的拷貝物件時,list內的可變資料型別變化,list2變化 list內的不可變資料型別變化,list2變化。總之 list變化list2一定變化 list 1,2,3,4,list2 list print list print list2 1,2,3,4,5 1,2,3,4,5...
操作字元 物件方法, 深淺拷貝
在乙個專案中,我們通常會通過例如substring,slice,concat等一些方法來操作字元,陣列,物件來獲取我們想要的結果 首先我覺得,所有的操作應該對深淺拷貝有乙個認識,因為有時候我們需要利用淺拷貝的特性來達到一些功能效果,更多的時候我們需要深拷貝來複製物件和陣列,在不影響原有資料的基礎上來...