面試題:深拷貝和淺拷貝(重點(diǎn))

一、數(shù)據(jù)類型存儲

基本類型(保存在棧內(nèi)存中)

引用類型(保存在堆內(nèi)存中,引用數(shù)據(jù)類型的變量是一個指向堆內(nèi)存中中實(shí)際對象的引用,存在棧中)

二、淺拷貝

淺拷貝,指的是創(chuàng)建新的數(shù)據(jù),這個數(shù)據(jù)有著原始數(shù)據(jù)屬性值的一份精確拷貝如果屬性是基本類型,拷貝的就是基本類型的值。如果屬性是引用類型,拷貝的就是內(nèi)存地址即淺拷貝是拷貝一層,深層次的引用類型則共享內(nèi)存地址下面簡單實(shí)現(xiàn)一個淺拷貝

functionshallowClone(obj){

????const?newObj?=?{};

????for(let?prop?in?obj)?{

????????if(obj.hasOwnProperty(prop)){

????????????newObj[prop]?=?obj[prop];

????????}

????}

????return?newObj;

}

在JavaScript中,存在淺拷貝的現(xiàn)象有:

Object.assign

Array.prototype.slice(),?Array.prototype.concat()

使用拓展運(yùn)算符實(shí)現(xiàn)的復(fù)制

Object.assign

varobj?=?{

age:18,

nature:?['smart','good'],

names:?{

name1:'fx',

name2:'xka'

},

love:function(){

console.log('fx?is?a?great?girl')

}

}

var newObj?=Object.assign({},?fxObj);

slice()

constfxArr?=?["One","Two","Three"]

constfxArrs?=?fxArr.slice(0)

fxArrs[1]?="love";

console.log(fxArr)//?["One",?"Two",?"Three"]

console.log(fxArrs)//?["One",?"love",?"Three"]

concat()

constfxArr?=?["One","Two","Three"]

constfxArrs?=?fxArr.concat()

fxArrs[1]?="love";

console.log(fxArr)//?["One",?"Two",?"Three"]

console.log(fxArrs)//?["One",?"love",?"Three"]

拓展運(yùn)算符

constfxArr?=?["One","Two","Three"]

constfxArrs?=?[...fxArr]

fxArrs[1]?="love";

console.log(fxArr)//?["One",?"Two",?"Three"]

console.log(fxArrs)//?["One",?"love",?"Three"]

三、深拷貝

深拷貝開辟一個新的棧,兩個對象屬性完成相同,但是對應(yīng)兩個不同的地址,修改一個對象的屬性,不會改變另一個對象的屬性

常見的深拷貝方式有:

_.cloneDeep()

jQuery.extend()

JSON.stringify()

手寫循環(huán)遞歸

_.cloneDeep()

const_?=require('lodash');

constobj1?=?{

a:1,

b:?{f:?{g:1}?},

c:?[1,2,3]

};

constobj2?=?_.cloneDeep(obj1);

console.log(obj1.b.f?===?obj2.b.f);//?false

jQuery.extend()

const$?=require('jquery');

constobj1?=?{

a:1,

b:?{f:?{g:1}?},

c:?[1,2,3]

};

constobj2?=?$.extend(true,?{},?obj1);

console.log(obj1.b.f?===?obj2.b.f);//?false

JSON.stringify()

constobj2=JSON.parse(JSON.stringify(obj1));

但是這種方式存在弊端,會忽略undefined、symbol和函數(shù)

constobj?=?{

name:'A',

name1:undefined,

name3:function(){},

name4:Symbol('A')

}

constobj2?=JSON.parse(JSON.stringify(obj));

console.log(obj2);//?{name:?"A"}

循環(huán)遞歸

functiondeepClone(obj,?hash?=?new?WeakMap()){

if(obj?===null)returnobj;//?如果是null或者undefined我就不進(jìn)行拷貝操作

if(objinstanceofDate)returnnewDate(obj);

if(objinstanceofRegExp)returnnewRegExp(obj);

//?可能是對象或者普通的值??如果是函數(shù)的話是不需要深拷貝

if(typeofobj?!=="object")returnobj;

//?是對象的話就要進(jìn)行深拷貝

if(hash.get(obj))returnhash.get(obj);

letcloneObj?=newobj.constructor();

//?找到的是所屬類原型上的constructor,而原型上的?constructor指向的是當(dāng)前類本身

hash.set(obj,?cloneObj);

for(letkeyinobj)?{

if(obj.hasOwnProperty(key))?{

//?實(shí)現(xiàn)一個遞歸拷貝

cloneObj[key]?=?deepClone(obj[key],?hash);

}

}

returncloneObj;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容