成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

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

lixiang / 3070人閱讀

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

對(duì)象的淺拷貝:

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

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" }
對(duì)象的深拷貝:

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

Object.assign()

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

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

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

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ù)制對(duì)象的name 和 grade.chi ,源對(duì)象的name沒(méi)有變化,但是grade.chi卻被改變了。因此我們可以看出Object.assign()拷貝的只是屬性值,假如源對(duì)象的屬性值是一個(gè)指向?qū)ο蟮囊?,它也只拷貝那個(gè)引用值。
也就是說(shuō),對(duì)于Object.assign()而言, 如果對(duì)象的屬性值為簡(jiǎn)單類(lèi)型(string, number),通過(guò)Object.assign({},srcObj);得到的新對(duì)象為‘深拷貝’;如果屬性值為對(duì)象或其它引用類(lèi)型,那對(duì)于這個(gè)對(duì)象而言其實(shí)是淺拷貝的。這是Object.assign()特別值得注意的地方。
多說(shuō)一句,Object.assign({}, src1, src2); 對(duì)于scr1和src2之間相同的屬性是直接覆蓋的,如果屬性值為對(duì)象,是不會(huì)對(duì)對(duì)象之間的屬性進(jìn)行合并的。

深拷貝的實(shí)現(xiàn)

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

JSON.parse() 和 JSON.stringify()

JSON.parse() 和 JSON.stringify() 算是對(duì) 深拷貝的一個(gè)無(wú)腦實(shí)現(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并沒(méi)有改變?cè)紝?duì)象,實(shí)現(xiàn)了基本的深拷貝。
但是用JSON.parse()和JSON.stringify()會(huì)有一個(gè)問(wèn)題。
JSON.parse()和JSON.stringify()能正確處理的對(duì)象只有Number、String、Array等能夠被json表示的數(shù)據(jù)結(jié)構(gòu),因此函數(shù)這種不能被json表示的類(lèi)型將不能被正確處理。比如

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)過(guò)轉(zhuǎn)換之后,function丟失了,因此JSON.parse()和JSON.stringify()還是需要謹(jǐn)慎使用。

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

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

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

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

但是數(shù)組的深拷貝方法要相對(duì)簡(jiǎn)單一些可以理解為數(shù)組方法中那些會(huì)改變?cè)瓟?shù)組的方法,比如

concat

slice

es6 的Array.from

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93871.html

相關(guān)文章

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

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

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

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

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

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

    shenhualong 評(píng)論0 收藏0
  • 淺談JavaScript的淺拷貝拷貝

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

    娣辯孩 評(píng)論0 收藏0
  • JavaScript 中的拷貝

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

    Tonny 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<