淺析---淺拷貝與深拷貝

? ? ? ? ? 拷貝(也稱克隆),指的是我們對(duì)從服務(wù)器請(qǐng)求回來的數(shù)據(jù),進(jìn)行"復(fù)制",我們可以對(duì)副本進(jìn)行修改等操作,不能影響到原來的數(shù)據(jù),如果修改的數(shù)據(jù)不理想,可以在不向服務(wù)器從新發(fā)送請(qǐng)求的情況下,返回到原來的數(shù)據(jù),

? ? ? ? ? 淺拷貝和深拷貝的區(qū)別是:淺拷貝只會(huì)拷貝對(duì)象最外部的一層,至于更深層次的對(duì)象,則依然是通過引用指向同一塊堆內(nèi)存.(意思是,拷貝之后的對(duì)象發(fā)生了變化,原對(duì)象也會(huì)發(fā)生變化);而深拷貝在一定程度上,解決了這個(gè)問題


淺拷貝

????????// 淺拷貝函數(shù)

????????????function shallowClone(oldobj) {

????????????? ????const obj = { };? ?//const 常量

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

? ? ????????????????????obj [i] = oldobj [i];

????????????????? }

????????????????? return obj;

????????????}

????????// 被克隆對(duì)象

????????const oldObj = {

? ????????????????a: 1,

? ????????????????b: [ 'e', 'f', 'g' ],

? ????????????????c: { h: { i: 2 } }

? ? ? ? ?};

????????const newObj = shallowClone(oldObj);

????????console.log(newObj.c.h, oldObj.c.h);? ? ?// { i: 2 } { i: 2 }??

????????console.log(oldObj.c.h === newObj.c.h);? ? // true

????????newObj.c.h.i = 'change';

? ? ? ? console.log(newObj.c.h, oldObj.c.h);? ?// { i: 'change' } { i: 'change' }

????????// 改變newobj的值,oldobj的值也會(huì)變(說明他們指向了同一段堆內(nèi)存),這種效果并不是我們想要的,所以,出現(xiàn)了深拷貝

深拷貝

? ? 第一種方法--------深拷貝函數(shù)

```

//使用遞歸的方式實(shí)現(xiàn)數(shù)組、對(duì)象的深拷貝

function deepClone1(obj) {

? //判斷拷貝的要進(jìn)行深拷貝的是數(shù)組還是對(duì)象,是數(shù)組的話進(jìn)行數(shù)組拷貝,對(duì)象的話進(jìn)行對(duì)象拷貝

? var objClone = Array.isArray(obj) ? [] : {};

? //進(jìn)行深拷貝的不能為空,并且是對(duì)象或者是

? if (obj && typeof obj === "object") {

? ? for (key in obj) {

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

? ? ? ? if (obj[key] && typeof obj[key] === "object") {

? ? ? ? ? objClone[key] = deepClone1(obj[key]);

? ? ? ? } else {

? ? ? ? ? objClone[key] = obj[key];

? ? ? ? }

? ? ? }

? ? }

? }

? return objClone;

原文鏈接:https://blog.csdn.net/chentony123/article/details/81428803

```

? ??????????????var oldobj={

????????????????????name:"apple",

????????????????????price:28,

????????????????????des:{a:{i:3}}

????????????????}

????????????????????var? newobj = deepCopy(oldobj);

????????????????????console.log(newobj,oldobj);? // { i : 3 },{ i : 3 }

????????????????????newobj.des.a.i=7;

? ? ? ? ? ? ? ? ? ? console.log(newobj,oldobj);// { i : 7 },{ i : 3 }? ? ?//新對(duì)象的 i 值變了,原對(duì)象的 i 值并沒有變

第二種方法------json.parse(),和json.stringify()方法

?????????????var oldobj={

????????????????????name:"apple",

????????????????????price:28,

????????????????????des:{a:{i:3}}

????????????????}

? ? ? ? ? ? ? ? var? newobj = JSON.parse(JSON.stringify(oldobj));

? ? ? ? ? ? ? ? console.log(newobj,oldobj);? // { i : 3 },{ i : 3 }

? ? ? ? ? ? ? ? ?newobj.des.a.i=7;?

? ? ? ? ? ? ? ? ?console.log(newobj,oldobj);// { i : 7 },{ i : 3 }? ? ?//得到的效果是和深拷貝函數(shù)的效果一樣

但是,深拷貝的兩種方法,都只能解決普通的深拷貝問題,特殊的對(duì)象(函數(shù),正則對(duì)象,構(gòu)造函數(shù),稀疏數(shù)組),這兩種方法還解決不了.

????????????functionPerson(name){

????????????????????this.name=name;

????????????}

? ? ? ? ? var lili= new Person("lili")

????????????function say(){

????????????????????console.log("hi")

????????????}

????????????var oldobj= {

????????????????????a:lili,

????????????????????b:say,

????????????????????c:new Array(1),

????????????????????d:RegExp("abc","i")

????????????}

????????var newobj= deepcopy(oldobj);

????????console.log(newobj.a,oldobj.a);????? //object? ?, Person? //構(gòu)造函數(shù)的指向不一樣

? ? ? ? console.log(newobj.b,oldobj.b);? ? ? //function , function? 拷貝函數(shù)打印的效果是對(duì)的,json.parse方法不行,打印的新對(duì)象為空

? ? ? ? console.log(newobj.c,oldobj.c);? ? ? // {? }, [ empty ]

????????console.log(newobj.d,oldobj.d);? ? ?// {? },? / abc / i


總結(jié):一般情況下,深拷貝的兩種方法就應(yīng)經(jīng)夠用了,如果遇到處理特殊對(duì)象的問題,再具體問題具體分析吧.


```

// 深克隆

// 循環(huán)遍歷每一個(gè)元素,判斷是原始值還是引用值

// 如果是原始值,就直接賦值,如果是引用值,就再次判斷是object,還是array

// 新建 [] || {} 再賦值

// 循環(huán)遞歸

function deepclone (orign,target){

var target = target || {}

var toStr = Object.prototype.toString

for(var prop in orign){

if(orign.hasOwnProperty(prop)){

if(typeof(orign[prop]) == 'object' && typeof(orign[prop])== null){

if(toStr.call(orign[prop]) === '[Object Array]'){

target[prop] = []

} else {

target[prop] = {}

}

deepclone(orign[prop],target[prop])

}else {

target[prop] = orign[prop]

}

}

}

return target

}

```

最后編輯于
?著作權(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)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,584評(píng)論 0 13
  • 單例模式 適用場(chǎng)景:可能會(huì)在場(chǎng)景中使用到對(duì)象,但只有一個(gè)實(shí)例,加載時(shí)并不主動(dòng)創(chuàng)建,需要時(shí)才創(chuàng)建 最常見的單例模式,...
    Obeing閱讀 2,321評(píng)論 1 10
  • 《ijs》速成開發(fā)手冊(cè)3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 10...
    葉染柒丶閱讀 5,657評(píng)論 0 7
  • title: 原生js對(duì)象的淺拷貝和深拷貝的總結(jié) 這里是說明. 在此之前我們先復(fù)習(xí)兩個(gè)知識(shí)點(diǎn). 第一個(gè)知識(shí)點(diǎn):對(duì)象...
    KingJeason閱讀 936評(píng)論 1 8
  • 有這么一個(gè)人,于星星而言,看似遙不可及,卻又觸手可及。 遇見你的時(shí)候所有星星都落到我頭上 第一次知道張杰這個(gè)名字,...
    小巨人啊_閱讀 1,622評(píng)論 3 1

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