摘要:但是進(jìn)行的是淺拷貝,拷貝的是屬性值。對象展開符深拷貝的實現(xiàn)方式手動復(fù)制轉(zhuǎn)成再轉(zhuǎn)回來只有可以轉(zhuǎn)成格式的對象才可以這樣用,像沒辦法轉(zhuǎn)成沒被改到使用方法避免相互引用對象導(dǎo)致死循環(huán),如的情況四參考關(guān)于的淺拷貝和深拷貝
一、理解
淺拷貝只復(fù)制指向某個對象的指針,而不復(fù)制對象本身,新舊對象還是共享同一塊內(nèi)存。但深拷貝會另外創(chuàng)造一個一模一樣的對象,新對象跟原對象不共享內(nèi)存,修改新對象不會改到原對象。二、淺拷貝與深拷貝
淺拷貝:賦值時,基本數(shù)據(jù)類型按值傳遞,對象按引用傳遞
var a = 25; var b = a; b = 18; console.log(a);//25 console.log(b);//18 // b的修改并不會影響到a,因為它們是基本類型數(shù)據(jù)
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = obj1; obj2.b = 100; console.log(obj1); // { a: 10, b: 100, c: 30 } <-- b 被改到了 console.log(obj2); // { a: 10, b: 100, c: 30 } // obj2修改了b的值,同時obj1的b也會被修改,因為他們根本是同一個對象,這就是所謂的淺拷貝
深拷貝:
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c }; obj2.b = 100; console.log(obj1); // { a: 10, b: 20, c: 30 } <-- b 沒被改到 console.log(obj2); // { a: 10, b: 100, c: 30 }三、實現(xiàn)方式
淺拷貝的實現(xiàn)方式
(1)直接賦值,就是淺拷貝。對象直接復(fù)制,則新對象的改變也會修改到舊對象。
(2) Object.assign(target, ...sources)
Object.assign是ES6的新函數(shù)。Object.assign()方法可以把任意多個的源對象自身的可枚舉屬性拷貝給目標(biāo)對象,然后返回目標(biāo)對象。但是Object.assign()進(jìn)行的是淺拷貝,拷貝的是屬性值。假如源對象的屬性值是一個指向?qū)ο蟮囊茫仓豢截惸莻€引用值。
var obj = { a: {a: "hello", b: 21} }; var initalObj = Object.assign({}, obj); initalObj.a.a = "changed"; console.log(obj.a.a); // "changed"
(3)對象展開符...
var obj = [{index: 1, msg: "one"}, {index: 2, msg: "two"}]; var obj2 = [...obj]; console.log(obj2); //[{index: 1, msg: "one"}, {index: 2, msg: "two"}] obj2.push({index: 3, msg: "three"}); console.log(obj2); // [{index: 1, msg: "one"}, {index: 2, msg: "two"}, {index: 3, msg: "three"}] console.log(obj); // [{index: 1, msg: "one"}, {index: 2, msg: "two"}] obj2[1].msg = "two again"; console.log(obj2); // [{index: 1, msg: "one"}, {index: 2, msg: "two again"}, {index: 3, msg: "three"}] console.log(obj); // [{index: 1, msg: "one"}, {index: 2, msg: "two again"}]
深拷貝的實現(xiàn)方式
(1)手動復(fù)制
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
(2)轉(zhuǎn)成JSON再轉(zhuǎn)回來(只有可以轉(zhuǎn)成JSON格式的對象才可以這樣用,像function沒辦法轉(zhuǎn)成JSON)
var obj1 = { body: { a: 10 } }; var obj2 = JSON.parse(JSON.stringify(obj1)); obj2.body.a = 20; console.log(obj1); // { body: { a: 10 } } <-- 沒被改到 console.log(obj2); // { body: { a: 20 } } console.log(obj1 === obj2); // false console.log(obj1.body === obj2.body); // false
(3)使用var newObj = Object.create(oldObj)方法
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用對象導(dǎo)致死循環(huán),如initalObj.a = initalObj的情況 if(prop === obj) { continue; } if (typeof prop === "object") { obj[i] = (prop.constructor === Array) ? [] : Object.create(prop); } else { obj[i] = prop; } } return obj; } var str = {}; var obj = { a: {a: "hello", b: 21} }; deepClone(obj, str);四、參考
【1】關(guān)于JavaScript的淺拷貝和深拷貝
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/100164.html
摘要:在中可以通過添加一個參數(shù)來實現(xiàn)遞歸,調(diào)用就可以實現(xiàn)一個深拷貝。利用序列化實現(xiàn)一個深拷貝 在JavaScript中,對于Object和Array這類引用類型值,當(dāng)從一個變量向另一個變量復(fù)制引用類型值時,這個值的副本其實是一個指針,兩個變量指向同一個堆對象,改變其中一個變量,另一個也會受到影響。 這種拷貝分為兩種情況:拷貝引用和拷貝實例,也就是我們說的淺拷貝和深拷貝 淺拷貝(shallow...
摘要:引用類型值引用類型值是保存在堆內(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...
摘要:說明外層數(shù)組拷貝的是實例說明元素拷貝是引用深拷貝在堆中重新分配內(nèi)存,并且把源對象所有屬性都進(jìn)行新建拷貝,拷貝后的對象與原來的對象完全隔離,互不影響。中的方法可以實現(xiàn)深拷貝,源碼原理也是遞歸使用淺拷貝。 1.淺拷貝 當(dāng)把數(shù)組或?qū)ο蠛唵钨x值給其他變量的時候,實際上進(jìn)行的是淺拷貝,淺拷貝是拷貝引用,只是將拷貝后的引用指向同一個對象實例,彼此間的操作還會互相影響。 分為兩種情況:直接拷貝源對象...
摘要:而大多數(shù)實際項目中,我們想要的結(jié)果是兩個變量初始值相同互不影響。所以就要使用到拷貝分為深淺兩種深淺拷貝的區(qū)別淺拷貝只復(fù)制一層對象的屬性,而深拷貝則遞歸復(fù)制了所有層級。 為什么會用到淺拷貝和深拷貝 首先來看一下如下代碼 let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e = f = {a:...
摘要:而大多數(shù)實際項目中,我們想要的結(jié)果是兩個變量初始值相同互不影響。所以就要使用到拷貝分為深淺兩種深淺拷貝的區(qū)別淺拷貝只復(fù)制一層對象的屬性,而深拷貝則遞歸復(fù)制了所有層級。 為什么會用到淺拷貝和深拷貝 首先來看一下如下代碼 let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e = f = {a:...
閱讀 2568·2023-04-25 20:05
閱讀 2891·2023-04-25 17:56
閱讀 2207·2021-10-14 09:49
閱讀 2689·2019-08-29 15:10
閱讀 2928·2019-08-29 12:25
閱讀 425·2019-08-28 18:23
閱讀 763·2019-08-26 13:26
閱讀 1376·2019-08-23 18:21