摘要:深拷貝相比于淺拷貝速度較慢并且花銷較大。所以在賦值完成后,在棧內存就有兩個指針指向堆內存同一個數據。結果如下擴展運算符只能對一層進行深拷貝如果拷貝的層數超過了一層的話,那么就會進行淺拷貝那么我們可以看到和展開原算符對于深淺拷貝的結果是一樣。
JS中數據類型
基本數據類型: undefined、null、Boolean、Number、String和Symbol(ES6)
引用數據類型: Object(Array, Date, RegExp, Function)
深淺拷貝深淺拷貝只是針對引用類型的,因為引用類型是存放在堆內存中,在棧地址有一個或者多個地址來指向推內存的某一數據
淺拷貝:被復制對象的所有變量都含有與原來的對象相同的值,而所有的對其他對象的引用仍然指向原來的對象。
淺拷貝僅僅復制所考慮的對象,而不復制它所引用的對象,如果你修改了“副本”的值,那么原來的對象也會被修改
深拷貝:深拷貝是一個整個獨立的對象拷貝,深拷貝會拷貝所有的屬性,并拷貝屬性指向的動態分配的內存。當對象和它所引用的對象一起拷貝時即發生深拷貝。深拷貝相比于淺拷貝速度較慢并且花銷較大。
深拷貝把要復制的對象所引用的對象都復制了一遍。如果你修改了“副本”的值,那么原來的對象不會被修改,兩者是相互獨立的。
用例子看深淺拷貝 賦值實現淺拷貝let arr = [22, 44, 66, 88]; let co = arr; co[0] = 11; console.log(arr, co);
結果如圖:
我們本來想把 arr 賦值給 co ,當我們修改co數組中第一個元素時,卻發現了原始數組arr發生了改變
很顯然,這就是一個淺拷貝的例子
原理:JSON實現深拷貝
對于引用類型,賦值操作符只是把存放在棧內容中的指針賦值給另外一個變量。
所以在賦值完成后,在棧內存就有兩個指針指向堆內存同一個數據。
也就可以說兩個變量在共用著同一個數據,這就是淺拷貝。
let arr = [22, 44, 66, 88]; let jso = JSON.parse(JSON.stringify(arr)); jso[0] = 11; console.log(arr, jso);
結果如圖:
對比之前賦值的結果,我們發現原來的數組arr并沒有被改變,可以說兩者是相互獨立的
很顯然,這就是一個深拷貝的例子
原理:
JSON.parse() 方法用于將一個 JSON 字符串轉換為對象。
JSON.stringify() 方法用于將 JavaScript 值(通常為對象或數組)轉換為 JSON 字符串。
在JSON.stringify()完成后,對象就轉為了字符串,也就可以說實實在在的復制了一個值,不存在引用之說。
再利用JSON.parse()轉為對象,這樣達到深拷貝的目的
JSON實現深拷貝的缺陷:
來看下面例子:
let obj = { nul: null, und: undefined, sym: Symbol("sym"), str: "str", bol: true, num: 45, arr: [1, 4], reg: /[0-9]/, dat: new Date(), fun: function() {}, } console.log(JSON.parse(JSON.stringify(obj)))
結果如圖:
我們可以發現有些屬性被忽略了:
undefined
symbol
function
可以看得出來JSON實現深拷貝也有不足之處
ES6新特性實現拷貝 Object.assign()Object.assign方法用于對象的合并,將源對象(source)的所有可枚舉屬性,復制到目標對象(target)。
Object.assign(target, ...sources)
target目標對象。 sources源對象。 返回的是目標對象
let obj = { a: { a1: "a1" }, b: "b" } let ass = Object.assign({}, obj); ass.a.a1 = "aaa"; aconsole.log(obj, ass);
我們看下結果:
我們可以看到a1的值被改變,而b的值沒有被改變,說明了:
Obejct.assign()只能對一層進行深拷貝展開運算符(...)
如果拷貝的層數超過了一層的話,那么就會進行淺拷貝
對象的擴展運算符(...)用于取出參數對象的所有可遍歷屬性,拷貝到當前對象之中。
let obj = { a: { a1: "a1" }, b: "b" } let ass = {...obj}; ass.a.a1 = "aaa"; ass.b = "bbb"
結果如下:
擴展運算符只能對一層進行深拷貝
如果拷貝的層數超過了一層的話,那么就會進行淺拷貝
那么我們可以看到Object.assign()和展開原算符對于深淺拷貝的結果是一樣。
如果拷貝的層數超過了一層的話,那么就會進行淺拷貝
所以要慎用這兩個來進行拷貝!!!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100714.html
摘要:動手實現深拷貝利遞歸來實現對對象或數組的深拷貝。遞歸思路對屬性中所有引用類型的值進行遍歷,直到是基本類型值為止。深拷貝只對對象自有屬性進行拷貝測試數據拷貝方式其實也是一種繼承的方式,當然繼承還是有其他方法的感謝支持 深淺拷貝 基本類型 & 引用類型 ECMAScript中的數據類型可分為兩種: 基本類型:undefined,null,Boolean,String,Number,Symb...
摘要:圖數據類型圖引用類型深淺拷貝問題不知道什么是深拷貝和淺拷貝的請先去并在調試臺自己操作一下,這篇文章只會說明為何中會有這種問題。所以有的時候我們為了避免淺拷貝,會用一些方式實現深拷貝。 首先要了解的js基礎 基本數據類型:Object、undefined、null、Boolean、Number、String、Symbol (ES6新加) Object包括: Array 、Date 、R...
摘要:基本數據類型的復制很簡單,就是賦值操作,所以深淺拷貝也是針對,這類引用類型數據。它會拋棄對象的。另外,查資料過程中還看到這么一個詞結構化克隆算法還有這一篇資料也有參考,也寫得比較詳細了的深淺拷貝 基本數據類型的復制很簡單,就是賦值操作,所以深淺拷貝也是針對Object,Array這類引用類型數據。 淺拷貝對于字符串來說,是值的復制,而對于對象來說則是對對象地址的復制;而深拷貝的話,它不...
閱讀 2111·2021-11-23 10:06
閱讀 3476·2021-11-11 16:54
閱讀 3343·2019-08-29 17:31
閱讀 3569·2019-08-29 17:05
閱讀 2171·2019-08-26 13:36
閱讀 2159·2019-08-26 12:17
閱讀 524·2019-08-26 12:12
閱讀 1673·2019-08-26 10:19