為什么要使用深度克潞鹁洹锅必?
? ? 直接克隆的話,克隆類中的數(shù)組只是獲得了原始類中的數(shù)組指向惕艳。這樣的話搞隐,原始類和克隆類中的數(shù)組指向同一個(gè)空間,當(dāng)你需要操作克隆類中的數(shù)組時(shí)远搪,原始類的數(shù)組也會(huì)跟著改變劣纲,這一點(diǎn)是相當(dāng)不可以的,也不符合邏輯终娃。
在克隆之前味廊,我們得先搞清楚蒸甜,我們需要克隆些什么內(nèi)容。
? ? 以obj為例余佛,我們進(jìn)行分析:
????????var?obj?=?{
????????????name?:?"嫖老師",
????????????age?: 18,
????????????hobbies?:?['basketball',?'JavaScript',?'Vue']?,
????????????family?:?{
????????????????name?:?"皮皮歡樂(lè)家庭",
????????????????parents?:?{
????????????????????father?:?"大皮皮",
????????????????????mother?:?"皮皮媽"
????????????????}
????????????}
????????}
? ? 我們可以直觀的看出來(lái)obj中有原始值和引用值柠新。引用值為數(shù)組和對(duì)象,其中對(duì)象中辉巡,又有原始值name和引用值parents恨憎,parents中又有原始值father、mather郊楣。說(shuō)明憔恳,想要完成深度克隆,必須嵌套循環(huán)實(shí)現(xiàn)净蚤。我們需要一層一層的進(jìn)行克隆挚币。
? ? 首先我們使用 for in 遍歷出obj中的所有元素庆亡,再加以判斷细移∞忠基本思想可以總結(jié)為5個(gè)過(guò)程:
? ? ? ? 1、遍歷對(duì)象 for (var prop in obj)
? ? ? ? 2橘荠、判斷是不是原始值 (使用typeof()判斷)
? ? ? ? 3屿附、判斷是數(shù)組還是對(duì)象(使用toString()判斷)
? ? ? ? 4、建立響應(yīng)的數(shù)組或?qū)ο?/p>
? ? ? ? 5哥童、遞歸
代碼演示:
?????function?deepClone(origin,?target)?{????//傳參?origin?被克隆的類?挺份,target?需要克隆的類
????????????var?target?=?target?||?{};??//當(dāng)沒(méi)有傳target時(shí),給創(chuàng)建個(gè)空類
????????????toStr?=?Object.prototype.toString,??//把toString方法應(yīng)用出來(lái)
????????????arrStr?=?"[object?Array]"???//先設(shè)定一個(gè)array的toString返回值贮懈,方便比較
????????????for(var?prop?in?origin)?{???//用for?in?循環(huán)origin中所有的屬性
????????????????if(origin.hasOwnProperty(prop))?{?//判斷所得的屬性是否是自身的屬性匀泊,不能使用原型鏈上的屬性
????????????????????if(origin[prop] !== "null" && typeof(origin[prop])?==?'object')?{??//為turn時(shí),該屬性為引用值朵你。為false時(shí)探赫,該元素為原始值,并且這個(gè)屬性不能為null撬呢,為null克隆就沒(méi)有意義
????????????????????????//走到這一步,就可以明確妆兑,只有數(shù)組和類倆種情況魂拦,在進(jìn)行判斷?
????????????????????????if(toStr.call(origin[prop])?==?arrStr)?{????//判斷是不是數(shù)組
????????????????????????????target[prop]?=?[];??//是數(shù)組創(chuàng)建一個(gè)空數(shù)組
????????????????????????}else?{
????????????????????????????target[prop]?=?{};??//不是數(shù)組,就只能是類了
????????????????????????}
????????????????????????//在一個(gè)類中搁嗓,也可能有原始值芯勘、數(shù)組、類三種情況所有腺逛,我們需要再次對(duì)這個(gè)類再進(jìn)行循環(huán)
????????????????????????//此時(shí)荷愕,循環(huán)的出口就是,當(dāng)該屬性為原始值,所有以當(dāng)前的prop再次調(diào)用循環(huán)安疗,就可以實(shí)現(xiàn)循環(huán)遞歸
????????????????????????deepClone(origin[prop],target[prop]);???
????????????????????}else?{
????????????????????????target[prop]?=?origin[prop];????//直接賦值
????????????????????}
????????????????}
????????????}
????????}
運(yùn)行結(jié)果演示:
給obj1.hobbies數(shù)組push一個(gè)數(shù)據(jù)抛杨,看看obj中的hobbies是否有影響
? ? 深度克隆成功,倆個(gè)hobbies的空間指向并不是同一個(gè)荐类,達(dá)成了我們的需求怖现。