摘要:對(duì)象是的基本塊。和明紅明可以看到改變并沒(méi)有改變?cè)紝?duì)象,實(shí)現(xiàn)了基本的深拷貝。和能正確處理的對(duì)象只有等能夠被表示的數(shù)據(jù)結(jié)構(gòu),因此函數(shù)這種不能被表示的類(lèi)型將不能被正確處理。
對(duì)象介紹
js中包含兩種不同數(shù)據(jù)類(lèi)型的值: 基本類(lèi)型值和引用類(lèi)型值。 基本類(lèi)型值指的是簡(jiǎn)單的數(shù)據(jù)段,而引用類(lèi)型值指的是那些由可能由多個(gè)值構(gòu)成的對(duì)象。
js對(duì)象都是引用類(lèi)型,對(duì)象是某個(gè)特定引用類(lèi)型的實(shí)例。對(duì)象是js的基本塊。對(duì)象是屬性的集合,屬性是鍵值對(duì)。js中看到的大多數(shù)引用類(lèi)型都是Object類(lèi)型的實(shí)例,Object也是js中使用最多的一個(gè)類(lèi)型。
按引用賦值let obj1 = { name : "jack", number: 10 } let obj2 = obj1 // 將obj1的引用賦值給obj2 此時(shí)obj1、obj2指向同一塊內(nèi)存空間 obj2.name = "tom" console.log(obj1.name) // tom
但從一個(gè)變量像另一個(gè)變量復(fù)制引用類(lèi)型的值時(shí),同樣也會(huì)將存儲(chǔ)在變量對(duì)象中的值復(fù)制一份放到位新的變量分配的空間中。不同的是,這個(gè)值的副本實(shí)際是一個(gè)指針,而這個(gè)指針指向存儲(chǔ)在堆中的一個(gè)對(duì)象。復(fù)制操作結(jié)束后,兩個(gè)變量實(shí)際上將引用同一個(gè)對(duì)象。因此改變其中一個(gè)變量就會(huì)改變另一個(gè)變量。
對(duì)象的拷貝方式 1. 復(fù)制對(duì)象的原始方法是循環(huán)遍歷原始對(duì)象,然后一個(gè)接一個(gè)地復(fù)制每個(gè)屬性。let objCopy = {}; // objCopy 將存儲(chǔ) mainObj 的副本 function copy(mainObj) { let key; for (key in mainObj) { objCopy[key] = mainObj[key]; // 將每個(gè)屬性復(fù)制到objCopy對(duì)象 } return objCopy; } const mainObj = { a: 2, b: 5, c: { x: 7, y: 4, }, } console.log(copy(mainObj)); objCopy.c.x = 10086 console.log("mainObj.c.x", mainObj.c.x) // 10086
上面的代碼只復(fù)制了 mainObj 的可枚舉屬性。
如果原始對(duì)象中的一個(gè)屬性本身就是一個(gè)對(duì)象,那么副本和原始對(duì)象之間將共享這個(gè)對(duì)象,從而使其各自的屬性指向同一個(gè)對(duì)象。
2.淺拷貝淺拷貝是對(duì)象共用一個(gè)內(nèi)存地址,對(duì)象的變化相互影響。比如常見(jiàn)的賦值引用就是淺拷貝:
let obj1 = { name : "jack", number: 10 } let obj2 = obj1 // 將obj1的引用賦值給obj2 此時(shí)obj1、obj2指向同一塊內(nèi)存空間 obj2.name = "tom" console.log(obj1.name) // tom
let obj = { a: 1, b: { c: 2, }, } let newObj = Object.assign({}, obj); console.log(newObj); // { a: 1, b: { c: 2} } obj.a = 10; console.log(obj); // { a: 10, b: { c: 2} } console.log(newObj); // { a: 1, b: { c: 2} } newObj.a = 20; console.log(obj); // { a: 10, b: { c: 2} } console.log(newObj); // { a: 20, b: { c: 2} } newObj.b.c = 30; console.log(obj); // { a: 10, b: { c: 30} } console.log(newObj); // { a: 20, b: { c: 30} } // 注意: newObj.b.c = 30; 為什么呢..
bject.assign 只是淺拷貝。 newObj.b 和 obj.b 都引用同一個(gè)對(duì)象,沒(méi)有多帶帶拷貝,而是復(fù)制了對(duì)該對(duì)象的引用。任何對(duì)對(duì)象屬性的更改都適用于使用該對(duì)象的所有引用。
注意:原型鏈上的屬性和不可枚舉的屬性不能復(fù)制。
let someObj = { a: 2, } let obj = Object.create(someObj, { b: { value: 2, }, c: { value: 3, enumerable: true, }, }); let objCopy = Object.assign({}, obj); console.log(objCopy); // { c: 3 }
someObj 是在 obj 的原型鏈,所以它不會(huì)被復(fù)制。
屬性 b 是不可枚舉屬性。
屬性 c 具有 可枚舉(enumerable) 屬性描述符,所以它可以枚舉。 這就是為什么它會(huì)被復(fù)制。
ES6已經(jīng)有了用于數(shù)組解構(gòu)賦值的 rest 元素,和實(shí)現(xiàn)的數(shù)組字面展開(kāi)的操作符。
const array = [ "a", "c", "d", { four: 4 }, ]; const newArray = [...array]; console.log(newArray); // 結(jié)果 // ["a", "c", "d", { four: 4 }]
只對(duì)淺拷貝有效
3.深拷貝簡(jiǎn)單理解深拷貝是將對(duì)象放到一個(gè)新的內(nèi)存中,兩個(gè)對(duì)象的改變不會(huì)相互影響。
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)慎使用。
數(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/106404.html
摘要:在之前的文章專(zhuān)題之?dāng)?shù)據(jù)類(lèi)型和類(lèi)型檢測(cè)中我有講過(guò),中的數(shù)據(jù)類(lèi)型分為兩種,基本數(shù)據(jù)類(lèi)型和引用數(shù)據(jù)類(lèi)型,基本數(shù)據(jù)類(lèi)型是保存在棧的數(shù)據(jù)結(jié)構(gòu)中的是按值訪問(wèn),所以不存在深淺拷貝問(wèn)題。 前言 在開(kāi)發(fā)過(guò)程中,偶爾會(huì)遇到這種場(chǎng)景,拿到一個(gè)數(shù)據(jù)后,你打算對(duì)它進(jìn)行處理,但是你又希望拷貝一份副本出來(lái),方便數(shù)據(jù)對(duì)比和以后恢復(fù)數(shù)據(jù)。 那么這就涉及到了 JS 中對(duì)數(shù)據(jù)的深淺拷貝問(wèn)題,所謂深淺拷貝,淺拷貝的意思就是,...
摘要:接下來(lái)就讓我們更細(xì)致的探究中的深淺拷貝??偨Y(jié)以上對(duì)深拷貝和淺拷貝做了簡(jiǎn)單的介紹,在深拷貝的實(shí)現(xiàn)上也只介紹了最簡(jiǎn)單的實(shí)現(xiàn)形式,并未考慮復(fù)雜情況以及相應(yīng)優(yōu)化,想要對(duì)深拷貝有更深入的了解,需要大家花時(shí)間去深入研究,或者可以關(guān)注我后續(xù)文章的動(dòng)態(tài)。 對(duì)象和數(shù)組的拷貝對(duì)我來(lái)說(shuō)一直都是一個(gè)比較模糊的概念,一直有點(diǎn)一知半解,但是在實(shí)際工作中又偶爾會(huì)涉及到,有時(shí)候還會(huì)一不小心掉坑里,不知道大家有沒(méi)有同樣...
摘要:一篇文章徹底說(shuō)清的深拷貝淺拷貝這篇文章的受眾第一類(lèi)業(yè)務(wù)需要急需知道如何深拷貝對(duì)象的開(kāi)發(fā)者。這篇文章分享的目的更多還是希望用一篇文章整理清楚深淺拷貝的含義遞歸實(shí)現(xiàn)思路以及小伙伴們?nèi)绻褂昧诉@種黑科技一定要清楚這樣寫(xiě)的優(yōu)缺點(diǎn)。 一篇文章徹底說(shuō)清JS的深拷貝and淺拷貝 這篇文章的受眾 第一類(lèi),業(yè)務(wù)需要,急需知道如何深拷貝JS對(duì)象的開(kāi)發(fā)者。 第二類(lèi),希望扎實(shí)JS基礎(chǔ),將來(lái)好去面試官前秀操作...
摘要:一篇文章徹底說(shuō)清的深拷貝淺拷貝這篇文章的受眾第一類(lèi)業(yè)務(wù)需要急需知道如何深拷貝對(duì)象的開(kāi)發(fā)者。這篇文章分享的目的更多還是希望用一篇文章整理清楚深淺拷貝的含義遞歸實(shí)現(xiàn)思路以及小伙伴們?nèi)绻褂昧诉@種黑科技一定要清楚這樣寫(xiě)的優(yōu)缺點(diǎn)。 一篇文章徹底說(shuō)清JS的深拷貝and淺拷貝 這篇文章的受眾 第一類(lèi),業(yè)務(wù)需要,急需知道如何深拷貝JS對(duì)象的開(kāi)發(fā)者。 第二類(lèi),希望扎實(shí)JS基礎(chǔ),將來(lái)好去面試官前秀操作...
摘要:一篇文章徹底說(shuō)清的深拷貝淺拷貝這篇文章的受眾第一類(lèi)業(yè)務(wù)需要急需知道如何深拷貝對(duì)象的開(kāi)發(fā)者。這篇文章分享的目的更多還是希望用一篇文章整理清楚深淺拷貝的含義遞歸實(shí)現(xiàn)思路以及小伙伴們?nèi)绻褂昧诉@種黑科技一定要清楚這樣寫(xiě)的優(yōu)缺點(diǎn)。 一篇文章徹底說(shuō)清JS的深拷貝and淺拷貝 這篇文章的受眾 第一類(lèi),業(yè)務(wù)需要,急需知道如何深拷貝JS對(duì)象的開(kāi)發(fā)者。 第二類(lèi),希望扎實(shí)JS基礎(chǔ),將來(lái)好去面試官前秀操作...
摘要:它將返回目標(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ì)象,相互之間有...
閱讀 2822·2023-04-25 22:51
閱讀 2067·2021-10-11 10:58
閱讀 3319·2019-08-30 10:49
閱讀 1884·2019-08-29 17:09
閱讀 3143·2019-08-29 10:55
閱讀 853·2019-08-26 10:34
閱讀 3499·2019-08-23 17:54
閱讀 990·2019-08-23 16:06