js對(duì)象、數(shù)組拷貝

????????在js中,數(shù)據(jù)類型類型可分為值類型(基本類型)和引用類型。值類型有:字符串(String)、布爾(Boolean)、數(shù)字(Number)、對(duì)空(Null)、未定義(undefined)、Symbol。引用類型:對(duì)象(Object)、數(shù)組(Array)、函數(shù)(Function)。這兩種類型的不同,使得在拷貝的時(shí)候也會(huì)有差異。值類型拷貝的時(shí)候直接賦值就好,但是在引用類型的對(duì)象和數(shù)組中,如果直接整體賦值的話有的時(shí)候是會(huì)有問題的。在項(xiàng)目中,我們經(jīng)常需要保存一份原始數(shù)據(jù),然后拷貝一份原始數(shù)據(jù)進(jìn)行更改,那么如果這個(gè)數(shù)據(jù)是Object或者Array類型,我們直接拷貝的話,他們還是指向的同一個(gè)地址,所以,當(dāng)我們改變其中的一個(gè)值或者新增一個(gè)屬性時(shí),另一份也會(huì)跟著變化,這肯定不是我們想要的結(jié)果,那么今天就總結(jié)一下js中,對(duì)象、數(shù)組拷貝的問題。

????????拷貝的問題也是分為兩種,一種是淺拷貝、另一種是深拷貝。在總結(jié)之前,我們先定義一個(gè)較復(fù)雜的對(duì)象名為Obj,后面的代碼都是使用該對(duì)象進(jìn)行更改的,具體結(jié)構(gòu)如下:

let Obj = {

????name:'zhang',

????age:18,

????score:{

????????Chinese:98,

????????English:88,

????????Math:98

????},

????like:[{

????????????sports:5

? ? ? ? ? },

????????{

????????????sports:4

????????},{

????????????sports:3

????????}]

}

一、淺拷貝

1、淺拷貝之使用Object.assign方式

function ObjCopy1(){

????let Obj1 = Object.assign({},Obj,);

????Obj1.name = 'zhang1';

????Obj1.like[1].sports = 55;

????Obj1.score.Chinese = 100,

????console.log('Obj.name:',Obj.name,' Obj.like[1].sports:',Obj.like[1].sports,'? ????Obj.score.Chinese:',Obj.score.Chinese);

????console.log('Obj1.name:',Obj1.name,'? Obj1.like[1].sports',Obj1.like[1].sports,'? ????Obj1.score.Chinese:',Obj1.score.Chinese);

}

ObjCopy1();


Object.assign淺拷貝結(jié)果

2、淺拷貝之...運(yùn)算符實(shí)現(xiàn)

function ObjCopy2(){

????let Obj2 = {...Obj};

????Obj2.name = 'zhang1';

????Obj2.like[1].sports = 55;

????Obj2.score.Chinese = 100,

????console.log('Obj.name:',Obj.name,'? Obj.like[1].sports:',Obj.like[1].sports,'? ????Obj.score.Chinese:',Obj.score.Chinese);

????console.log('Obj2.name:',Obj2.name,'? Obj2.like[1].sports',Obj2.like[1].sports,'? ????Obj2.score.Chinese:',Obj2.score.Chinese);

}

ObjCopy2();


...運(yùn)算符淺拷貝結(jié)果

3、淺拷貝之一重循環(huán)直接遍歷

function ObjCopy3(Obj){

????let Obj3={};

????for (let item in Obj){

????????Obj3[item] = Obj[item]

????}

????Obj3.name = 'zhang1';

????Obj3.like[1].sports = 55;

? ? Obj3.score.Chinese = 100,

????console.log('Obj.name:',Obj.name,'? Obj.like[1].sports:',Obj.like[1].sports,'? ????Obj.score.Chinese:',Obj.score.Chinese);

????console.log('Obj3.name:',Obj3.name,'? Obj3.like[1].sports',Obj3.like[1].sports,'? ????Obj3.score.Chinese:',Obj3.score.Chinese);

}

一重循環(huán)遍歷淺拷貝結(jié)果

????????通過結(jié)果可以看到,通過以上三種方式實(shí)現(xiàn)的拷貝都是淺拷貝,當(dāng)嵌套多層Object或Array時(shí),我們更改value中的對(duì)象或Array的值時(shí),原始數(shù)據(jù)也跟著變化了。

二、深拷貝

1、深度拷貝之使用JSON.parse()和JSON.stringify()

function ObjCopy4(){

????let Obj4 = JSON.parse(JSON.stringify(Obj));

????Obj4.name = 'zhang1';

????Obj4.like[1].sports = 55;

????Obj4.score.Chinese = 100,

????console.log('Obj.name:',Obj.name,'? Obj.like[1].sports:',Obj.like[1].sports,'? ????Obj.score.Chinese:',Obj.score.Chinese);

????console.log('Obj4.name:',Obj4.name,'? Obj4.like[1].sports',Obj4.like[1].sports,'? ????Obj4.score.Chinese:',Obj4.score.Chinese);

}

ObjCopy4();

利用JSON.parse()和JSON.stringify()? 方法拷貝結(jié)果

2、利用遞歸,自定義深度拷貝

function ObjCopy5(){

function copy (Obj) {

? ? ? ? var newObj = Obj.constructor === Array ? [] : {};

? ? ? ? if(typeof Obj !== 'object'){

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? for(var i in Obj){

? ? ? ? ? newObj[i] = typeof Obj[i] === 'object' ?

? ? ? ? ? copy(Obj[i]) : Obj[i];

? ? ? ? }

? ? ? ? return newObj

}

var Obj5 = copy(Obj)

Obj5.name = 'zhang1';

Obj5.like[1].sports = 55;

Obj5.score.Chinese = 100,

console.log('Obj.name:',Obj.name,'? Obj.like[1].sports:',Obj.like[1].sports,'? Obj.score.Chinese:',Obj.score.Chinese);

console.log('Obj5.name:',Obj5.name,'? Obj5.like[1].sports',Obj5.like[1].sports,'? Obj5.score.Chinese:',Obj5.score.Chinese);

}

遞歸方法實(shí)現(xiàn)深度拷貝

????????這兩種方法都能實(shí)現(xiàn)深度拷貝,此處只是針對(duì)Object和Array,F(xiàn)unction的不一定能夠拷貝成功。一般情況下針對(duì)只含有Object和Array的對(duì)象拷貝時(shí),使用JSON.parse()和JSON.stringify()方法拷貝是非常簡(jiǎn)單的。此處我只總結(jié)了5種方法,如果有其它的方法,也希望大家能夠多分享哦。

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

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

  • JavaScript(面向?qū)ο?原型理解+繼承+作用域鏈和閉包+this使用總結(jié)) 一、面向?qū)ο?1、什么是面向?qū)?..
    老頭子_d0ec閱讀 328評(píng)論 0 0
  • 關(guān)于JavaScript的淺拷貝和深拷貝 在JS中有一些基本類型像是Number、String、Boolean,而...
    成都reactnative閱讀 342評(píng)論 0 0
  • 小編已經(jīng)更新了代碼部分,戳這里 一、數(shù)據(jù)類型 數(shù)據(jù)分為基本數(shù)據(jù)類型(String, Number, Boolean...
    grain先森閱讀 2,800評(píng)論 2 53
  • 1.引用類型有哪些?非引用類型有哪些 引用類型: 對(duì)象 object 數(shù)組 函數(shù) 正則非引用類型...
    怎么昵稱閱讀 312評(píng)論 0 0
  • 引用類型有哪些?非引用類型有哪些? JS中的數(shù)據(jù)類型分為基本類型和引用類型?;绢愋停簲?shù)值(number)、字符串...
    LeeoZz閱讀 313評(píng)論 0 0

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