亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

javascript對象的淺拷貝、深拷貝和Object.assign方法淺析

lixiang / 3094人閱讀

摘要:對象的淺拷貝淺拷貝是對象共用一個內(nèi)存地址,對象的變化相互影響。這是特別值得注意的地方。和能正確處理的對象只有等能夠被表示的數(shù)據(jù)結(jié)構(gòu),因此函數(shù)這種不能被表示的類型將不能被正確處理。

對象的淺拷貝:

淺拷貝是對象共用一個內(nèi)存地址,對象的變化相互影響。比如常見的賦值引用就是淺拷貝:

let srcObj = {"name": "lilei", "age": "20"};
let copyObj = srcObj;
copyObj.age = "22";
console.log("srcObj", srcObj);   // srcObj { name: "lilei", age: "22" }
console.log("copyObj", copyObj);  // copyObj { name: "lilei", age: "22" }
對象的深拷貝:

簡單理解深拷貝是將對象放到一個新的內(nèi)存中,兩個對象的改變不會相互影響。

Object.assign()

MDN上這樣介紹Object.assign(),"Object.assign() 方法用于將所有可枚舉的屬性的值從一個或多個源對象復(fù)制到目標(biāo)對象。它將返回目標(biāo)對象",好吧,并看不出是深拷貝還是淺拷貝,我們來測試一下

let srcObj = {"name": "lilei", "age": "20"};
let copyObj2 = Object.assign({}, srcObj, {"age": "21"});
copyObj2.age = "23";
console.log("srcObj", srcObj); //{ name: "lilei", age: "22" }

看起來好像是深拷貝了,那其實這里let copyObj2 = Object.assign({}, srcObj, {"age": "21"}); 我們把srcObj 給了一個新的空對象。同樣目標(biāo)對象為 {},我們再來測試下:

srcObj = {"name": "明", grade: {"chi": "50", "eng": "50"} };
copyObj2 = Object.assign({}, srcObj);
copyObj2.name = "紅";
copyObj2.grade.chi = "60";
console.log("新 objec srcObj", srcObj);  // { name: "明", grade: { chi: "60", eng: "50" } }

從例子中可以看出,改變復(fù)制對象的name 和 grade.chi ,源對象的name沒有變化,但是grade.chi卻被改變了。因此我們可以看出Object.assign()拷貝的只是屬性值,假如源對象的屬性值是一個指向?qū)ο蟮囊茫仓豢截惸莻€引用值。
也就是說,對于Object.assign()而言, 如果對象的屬性值為簡單類型(string, number),通過Object.assign({},srcObj);得到的新對象為‘深拷貝’;如果屬性值為對象或其它引用類型,那對于這個對象而言其實是淺拷貝的。這是Object.assign()特別值得注意的地方。
多說一句,Object.assign({}, src1, src2); 對于scr1和src2之間相同的屬性是直接覆蓋的,如果屬性值為對象,是不會對對象之間的屬性進(jìn)行合并的。

深拷貝的實現(xiàn)

有很多第三方庫實現(xiàn)了對象的深拷貝,比如常見的 Jquery 和 underscore ,比較未來的 lodash,實現(xiàn)源碼還沒仔細(xì)分析,分析之后再來補(bǔ)充。
不過,如果你沒有引入這些庫,對于深拷貝還有一個簡單的方法實現(xiàn)

JSON.parse() 和 JSON.stringify()

JSON.parse() 和 JSON.stringify() 算是對 深拷貝的一個無腦實現(xiàn),看例子:

srcObj = {"name": "明", grade: {"chi": "50", "eng": "50"} };
// copyObj2 = Object.assign({}, srcObj);
copyObj2 = JSON.parse(JSON.stringify(srcObj));
copyObj2.name = "紅";
copyObj2.grade.chi = "60";
console.log("JSON srcObj", srcObj); // { name: "明", grade: { chi: "50", eng: "50" } }

可以看到改變copyObj2并沒有改變原始對象,實現(xiàn)了基本的深拷貝。
但是用JSON.parse()和JSON.stringify()會有一個問題。
JSON.parse()和JSON.stringify()能正確處理的對象只有Number、String、Array等能夠被json表示的數(shù)據(jù)結(jié)構(gòu),因此函數(shù)這種不能被json表示的類型將不能被正確處理。比如

srcObj = {"name": "明", grade: {"chi": "50", "eng": "50"},
    "hello": function() {console.log("hello")}};
// copyObj2 = Object.assign({}, srcObj);
copyObj2 = JSON.parse(JSON.stringify(srcObj));
copyObj2.name = "紅";
copyObj2.grade.chi = "60";
console.log("JSON srcObj", copyObj2); //{ name: "紅", grade: { chi: "60", eng: "50" } }

可以看出,經(jīng)過轉(zhuǎn)換之后,function丟失了,因此JSON.parse()和JSON.stringify()還是需要謹(jǐn)慎使用。

后續(xù)再補(bǔ)充深拷貝實現(xiàn)思想。。。。

數(shù)組的深拷貝和淺拷貝

最后在補(bǔ)充一點數(shù)組的深拷貝和淺拷貝,同對象一樣數(shù)組的淺拷貝也是改變其中一個會相互影響,比如:

let srcArr = [1, 2, 3];
let copyArr = srcArr;
copyArr[0] = "0";
console.log("srcArr", srcArr); // ["0", 2, 3]

但是數(shù)組的深拷貝方法要相對簡單一些可以理解為數(shù)組方法中那些會改變原數(shù)組的方法,比如

concat

slice

es6 的Array.from

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/93871.html

相關(guān)文章

  • JavaScript系列--淺析JavaScript解析賦值、淺拷貝拷貝的區(qū)別

    摘要:它將返回目標(biāo)對象。有些文章說是深拷貝,其實這是不正確的。深拷貝相比于淺拷貝速度較慢并且花銷較大??截惽昂髢蓚€對象互不影響。使用深拷貝的場景完全改變變量之后對沒有任何影響,這就是深拷貝的魔力。 一、賦值(Copy) 賦值是將某一數(shù)值或?qū)ο筚x給某個變量的過程,分為: 1、基本數(shù)據(jù)類型:賦值,賦值之后兩個變量互不影響 2、引用數(shù)據(jù)類型:賦址,兩個變量具有相同的引用,指向同一個對象,相互之間有...

    laznrbfe 評論0 收藏0
  • 關(guān)于js的淺拷貝拷貝

    摘要:原文地址淺拷貝和深拷貝只針對像這樣的復(fù)雜對象的簡單來說,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了所有層級。淺拷貝通過來實現(xiàn)淺拷貝。 原文地址:http://www.silenceboy.com/201... 淺拷貝和深拷貝只針對像Object, Array這樣的復(fù)雜對象的.簡單來說,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了所有層級。 淺拷貝 通過 Object.ass...

    summerpxy 評論0 收藏0
  • 關(guān)于JavaScript的淺拷貝拷貝

    摘要:引用類型值引用類型值是保存在堆內(nèi)存中的對象,變量保存的只是指向該內(nèi)存的地址,在復(fù)制引用類型值的時候,其實只復(fù)制了指向該內(nèi)存的地址。 前言 要理解 JavaScript中淺拷貝和深拷貝的區(qū)別,首先要明白JavaScript的數(shù)據(jù)類型。JavaScript有兩種數(shù)據(jù)類型,基礎(chǔ)數(shù)據(jù)類型和引用數(shù)據(jù)類型。js的基本類型:undefined,null,string,boolean,number,s...

    shenhualong 評論0 收藏0
  • 淺談JavaScript的淺拷貝拷貝

    摘要:引用數(shù)據(jù)類型是存放在堆內(nèi)存中的,變量實際上是一個存放在棧內(nèi)存的指針,這個指針指向堆內(nèi)存中的地址。棧和堆的區(qū)別其實淺拷貝和深拷貝的主要區(qū)別就是數(shù)據(jù)在內(nèi)存中的存儲類型不同。這里,對存在子對象的對象進(jìn)行拷貝的時候,就是深拷貝了。 數(shù)據(jù)類型 在開始拷貝之前,我們從JavaScript的數(shù)據(jù)類型和內(nèi)存存放地址講起。數(shù)據(jù)類型分為基本數(shù)據(jù)類型 和引用數(shù)據(jù)類型 基本數(shù)據(jù)類型主要包括undefin...

    娣辯孩 評論0 收藏0
  • JavaScript 中的拷貝

    摘要:基本類型指的是簡單的數(shù)據(jù)段,而引用類型指的是一個對象保存在堆內(nèi)存中的地址,不允許我們直接操作內(nèi)存中的地址,也就是說不能操作對象的內(nèi)存空間,所以,我們對對象的操作都只是在操作它的引用而已。 工作中經(jīng)常會遇到需要復(fù)制 JavaScript 數(shù)據(jù)的時候,遇到 bug 時實在令人頭疼;面試中也經(jīng)常會被問到如何實現(xiàn)一個數(shù)據(jù)的深淺拷貝,但是你對其中的原理清晰嗎?一起來看一下吧! 一、為什么會有深淺...

    Tonny 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<