深拷貝和淺拷貝的區(qū)別
深拷貝和淺拷貝最根本的區(qū)別在于是否真正復制一個對象的實體,而不是引用。舉個爪子,假如 同學A 抄同學 B 的筆記,B給A同學一個復制鏈接,B 筆記做了修改,A同學的筆記也變了 這叫淺拷貝,
如果 A抄同學的筆記,又獨立建了一份新的,互不影響,這是是你拷貝
官方說法
淺拷貝 只是增加了一個指針指向已存在的內(nèi)存地址,
深拷貝 是增加了一個指針并且申請了一個新的內(nèi)存,使這個增加的指針指向這個新的內(nèi)存淺拷貝的方法
Object.assgin()
Array.prototype.slice()
Array.prototype.concat()
b=[...a]深拷貝
- JSON.parse(JSON.stringify(obj))
- 手寫
let obj = {
name:'hello',
type:[1,2,3],
content:{
title:'nihao'
}
}
// 手寫深拷貝
// WeakMap跟Map結(jié)構(gòu)類似,也擁有g(shù)et、has、delete等方法,使用法和使用途都一樣。
// WeakMap只接受對象作為鍵名,但null不能作為鍵名
// WeakMap不支持clear方法,不支持遍歷,也就沒有了keys、values、entries、forEach這4個方法,也沒有屬性size
// WeakMap 鍵名中的引用類型是弱引使用,
// 假如這個引使用類型的值被垃圾機制回收了,WeakMap實例中的對應鍵值對也會消失。WeakMap中的key不計入垃圾回收,即若只有WeakMap中的key對某個對象有引用,那么此時執(zhí)行垃圾回收時就會回收該對象,而Map中的key是計入垃圾回收
// 判斷類型是不是對象
function checkType(source) {
// 1種寫法
return Object.prototype.toString.call(source).slice(8,-1)
// 2種寫法
// return typeof obj === 'object' && obj != null;
}
function copyDeep(source,map = new WeakMap()) {
// 判斷如果參數(shù)是不是一個對象,如果不是返回該參數(shù)
let cloneObj, type = checkType(source)
if(type =='object'){
cloneObj = {}
}else if(type =='Array'){
cloneObj = []
}else{
return source
}
// 如果拷貝過該對象,則直接返回該對象
if(map.get(source)){
return source
}
// 如果不存在,我們放到map對象里
map.set(source,cloneObj)
//遞歸拷貝
for(key in source){
cloneObj[key] = copyDeep[source[key],map]
}
//最后返回克隆的值
return cloneObj
}
console.log(copyDeep(obj))

image.png