摘要:什么是深拷貝淺拷貝見名知義,無論是深拷貝還是淺拷貝,都是的問題。使用如下以上就是關于中的深拷貝與淺拷貝的知識和如何進行深拷貝的知識了,如果有錯或者有其他方式的話,歡迎在下面留言評論啦
前言 最近在寫項目的時候涉及到一些父子組件傳遞個對象或者數組通信啥的,或者是直接復制添加對象啥的,直接使用賦值的時候總會出錯。一查原來是淺拷貝的問題,就從網上找了點資料,匯總到這里來了。
1 什么是深拷貝&淺拷貝見名知義,無論是深拷貝還是淺拷貝,都是 copy 的問題。就是 copy 的時候出現的兩種情況。區分起來也挺簡單的,舉個例子,假設 B 是 A 復制過來的,當我們修改 A 的時候,B 也隨之改變了,那么這個就是淺拷貝,那要是 B 沒有隨 A 一起改變的話,那么這個就深拷貝了。
2 現實場景首先呢,我們先要明白在 Javascript 中,有 5 種簡單數據類型(也稱為基本數據類型),分別是 Undefined,Null,String,Number,Boolean,還有 1 種復雜數據類型即 Object,(ES6 新出的 Symbol 數據類型就先不討論了)
2.1 基本數據類型對于基本數據類型的復制就談不上什么深拷貝和淺拷貝了,對于基本數據類型來說,他們的值在棧內存中占據著固定大小的空間,并被保存在棧內存中。假設 變量 b 復制 基本數據類型變量 a,那么 b 會內存中占據自己的空間,和 a 就沒啥關系了,大家各管各的,互不干涉。
let a = 2; let b = a; b = 4; console.log(a); // 2 console.log(b); // 42.2 復雜數據類型(Object)
對于對象的話,他是引用類型,復制起來就要區分淺拷貝和深拷貝了,因為 Object 是引用類型,他真正的值保存在堆內存中,他在棧內存存儲是變量名和指向該對象值的指針(就是一個地址),如下圖所示。
所以當我們用平常用一個變量去復制一個 Object 類型的變量的時候,復制的是他的指針地址而已,所以兩個變量最終都指向同一個變量,大家要改一起改,這就是淺拷貝啦,如下
let obj1 = {name:"kk",age:12,desc:"源對象"} let obj2 = obj1; obj2.desc = "目標對象" console.log(obj1); //{name:"kk",age:12,desc:"目標對象"} 此處源對象跟著一起變了 console.log(obj2); // {name:"kk",age:12,desc:"目標對象"}
啥,不信?!,那就看圖
如何
但是在我們日常的使用當中,Object 類型的淺拷貝的行為會讓我們很迷,我復制這個對象就是想復制他的值而已啦,不要復制人家個值就和他綁到一塊了,跟他一起「同生共死」。所以啊,當我們想按照我們復制的想法,就只復制他的值用來自己用,他的是他的,我的是我的,大家井水不犯河水。接下來就要說咋辦了。
對于對象的深拷貝,搜集了網上的資料,就有下面三種方法
3.1 slice()&concat()這個是針對數組的深拷貝,可以通過這兩個方法實現對數組的深拷貝,如下
let arr = [1,2,3,4] let arr2 = arr.slice(); arr[0] = 0; console.log(arr); //[1,2,3,4] console.log(arr2); //[1,2,3,4]
concat 同理可得,不過這兩個方法有個問題,slice() 和 concat() 方法能夠深拷貝的就只有數組的一級屬性,但是如果是多維數組的話,那么只有一級屬性的值是深拷貝,往下就都是淺拷貝了,如下所示
let arr = [[1,2],2,3,4] let arr2 = arr.concat(); arr[0][0] = 0; arr[1] = 1; console.log(arr); //[[0,2],1,3,4] console.log(arr2); //[[0,2],2,3,4] // arr2[1] 沒變,但是 arr2[0] 跟著一起改了3.2 JSON 的騷操作
通過 JSON 的 stringify, parase 操作也可以實現對象的深拷貝。
let obj1 = {name:"kk",age:12,desc:"源對象"} let obj2 = JSON.parase(JSON.stringify(obj1)); obj2.desc = "目標對象"; console.log(obj1); //{name:"kk",age:12,desc:"源對象"} 此處源對象就沒有一起變了 console.log(obj2); // {name:"kk",age:12,desc:"目標對象"}
此法數組和對象都可以用。
3.3 自己寫一個深拷貝函數自己動手,豐衣足食
function deepCopy(obj) { let newObj = Array.isArray(obj) ? [] : {}; if (obj && typeof obj === "object") { for (let key in obj) { if (obj.hasOwnProperty(key)) { //判斷ojb子元素是否為對象,如果是,遞歸復制 if (obj[key] && typeof obj[key] === "object") { newObj[key] = deepCopy(obj[key]); } else { //如果不是,簡單復制 newObj[key] = obj[key]; } } } } return newObj; } let a = [1,2,3]; let b = deepCopy(a); a[0] = 0; console.log(a); //[0,2,3] console.log(a); // [1,2,3]3.4 JQ 的 extend 方法
這個就直接放文檔了
$.extend( [deep ], target, object1 [, objectN ] )
deep:如果設為true,則遞歸合并即深拷貝。
target:待修改對象。
object1:待合并到第一個對象的對象。
objectN:待合并到第一個對象的對象。
使用如下
let a = [1,2,3], let b = $.extend(true,[],a); a[0]=1; console.log(a); // [0,2,3] console.log(b); // [1,2,3]
以上就是關于 JS 中的深拷貝與淺拷貝的知識和如何進行深拷貝的知識了,如果有錯或者有其他方式的話,歡迎在下面留言評論啦
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99393.html
摘要:中的深拷貝與淺拷貝說到深淺拷貝的時候就不得不說一下中的變量類型了基本類型按值存放在棧內存中的簡單數據段可以直接訪問引用類型存放在堆內存中的對象變量保存的是一個指向存放數據位置的指針訪問引用類型的值時首先從棧中獲取到存放該數據位置的指針然后再 JS中的深拷貝與淺拷貝 說到深淺拷貝的時候就不得不說一下JS中的變量類型了: 基本類型: undefined、null、boolean、numb...
摘要:深拷貝和淺拷貝最根本的區別在于是否是真正獲取了一個對象的復制實體,而不是引用,深拷貝在計算機中開辟了一塊內存地址用于存放復制的對象,而淺拷貝僅僅是指向被復制的內存地址,如果原地址中對象被改變了,那么淺拷貝出來的對象也會相應改變。 深拷貝和淺拷貝最根本的區別在于是否是真正獲取了一個對象的復制實體,而不是引用, 深拷貝在計算機中開辟了一塊內存地址用于存放復制的對象, 而淺拷貝僅僅是指向被...
摘要:案例中的賦值就是典型的淺拷貝,并且深拷貝與淺拷貝的概念只存在于引用類型。修改修改經測試,也只能實現一維對象的深拷貝。經過驗證,我們發現提供的自有方法并不能徹底解決的深拷貝問題。 在說深拷貝與淺拷貝前,我們先看兩個簡單的案例: //案例1 var num1 = 1, num2 = num1; console.log(num1) //1 console.log(num2) //1 num...
摘要:而引用類型值是指那些保存堆內存中的對象,意思是變量中保存的實際上只是一個指針,這個指針指向內存中的另一個位置,該位置保存對象。而堆內存主要負責對象這種變量類型的存儲。我們需要明確一點,深拷貝與淺拷貝的概念只存在于引用類型。 深拷貝和淺拷貝 說起深拷貝和淺拷貝,首先我們來看兩個栗子 // 栗子1 var a = 1,b=a; console.log(a); console.log(b) ...
摘要:深拷貝淺拷貝本文主要對深拷貝淺拷貝的解釋及實現做一下簡單記錄。之所以會有深拷貝與淺拷貝之分,是因為不同數據類型的數據在內存中的存儲區域不一樣。但注意,只能做一層屬性的淺拷貝。 深拷貝VS淺拷貝 本文主要對深拷貝&淺拷貝的解釋及實現做一下簡單記錄。原文鏈接,歡迎star。 之所以會有深拷貝與淺拷貝之分,是因為不同數據類型的數據在內存中的存儲區域不一樣。 堆和棧是計算機中劃分出來用來存儲的...
閱讀 2134·2021-10-14 09:43
閱讀 2197·2019-08-30 15:55
閱讀 725·2019-08-30 14:23
閱讀 2019·2019-08-30 13:21
閱讀 1234·2019-08-30 12:50
閱讀 2198·2019-08-29 18:46
閱讀 2280·2019-08-29 17:28
閱讀 2359·2019-08-29 17:21