js 物件深拷貝 深拷貝與淺拷貝

2021-10-12 05:31:43 字數 2681 閱讀 8323

前言:最近在複習一些面試的知識點,剛剛好複習到了這一部分,於是就寫下這篇文章記錄一下。

一 、值型別和引用型別

在學習深拷貝和淺拷貝之前,我們先來了解一下js的變數型別。

值型別 vs 引用型別

值型別:值型別主要有:number,string,boolean,symbol,null,undefined 這6種。

我們來看下**:

我們可以看到將a賦值給了b,然後將a的值改變,再列印b,發現b還是100.

引用型別:object,array,regexp,date,function。

看下**:

a為乙個物件,裡面有age,將b賦值成a,然後修改b.age,發現a物件裡面的age也跟著改變了。

深入分析一下:

1、當我們的****現變數的時候,瀏覽器會將變數存放棧中,這個棧就是我們計算機的儲存結構。如上面值型別中的定義的變數a和b,就會放到棧中儲存起來。

由上圖可以看到,當重新定義變數b,並且將b賦值為a的時候,棧就會重新開闢乙個儲存位置,這時候改變b的值,是不會影響到a變數的值得的。

2、當我們使用到js的引用型別變數的時候,這時候就會涉及到堆的儲存(在計算機變數儲存的時候,堆和棧是同時存在的,棧是從上往下累加,堆是相反)。

當我們將變數a賦值成乙個物件的時候,瀏覽器會在堆中生成乙個記憶體位址(記憶體位址1),然後把這個物件,放到堆裡面儲存起來。這時候,變數a儲存的是乙個位址,並且在棧中儲存起來。這時候將變數b賦值成a,b就會同樣的指向記憶體位址1。這時候去改變b的內容,a中的內容也是會發生改變的。這是因為b拷貝了a在棧中的堆位址,都指向a在堆中的屬性值,當a放生改變時,b屬性值也會改變,因為b也指向相同的堆記憶體。

那麼有沒有辦法將 引用型別 像 值型別 賦值一樣去賦值呢?

接下來就需要用到js的淺拷貝和深拷貝了來解決上面出現的問題了(而變數 a和 b 指向同一位址,當該位址的資料改變時,所有使用該位址的變數全部改變(同一資料))。

淺拷貝

既然物件資料型別 是由基本資料型別組成的,而基本資料型別可以正常賦值、比較,那我們就把物件型別變成乙個個的基本型別進行操作,所以我們可以遍歷物件中的內容,乙個乙個的進行賦值,進行一層的拷貝,這就是淺拷貝。下面我們來手寫乙個淺拷貝

//淺拷貝        function shallowclone(source = {}) ,                key;            for(key in source)            }            return result;        }
然後我們來測試一下,發現是拷貝成功了,

但是這只能拷貝一層,要是物件有多層巢狀的話,就不行了。如下:

這時候,我們需要使用到深拷貝來解決這個問題。

深拷貝

相對於淺拷貝只能拷貝一層,深拷貝可以無限層次的拷貝。

深拷貝實現的思路:

**如下:

// 深拷貝        function deepclone(source = {})             // 初始化返回結果            let result;            if (source instanceof array)  else ;            }            for (let key in source)             }            return result;        }
然後我們來測試一下:

會發現,深拷貝成功了。

還有一種非常簡單的深拷貝方法,相信大家也經常用到過,就是使用系統自帶的json來做深拷貝。

function clonejson(source)
但是他的缺陷就是:物件裡面的函式無法被拷貝,原型鏈裡面的屬性無法被拷貝。

總結

其實我們有很多其他的辦法實現拷貝,比如:es6的assign方法(淺拷貝);通過immutablejs實現深拷貝; jq的extend方法等等。我們可以根據不同的業務場景進行不同的選擇。無論是深拷貝還是淺拷貝,一旦資料量大了起來,都會出現效能問題。

js物件淺拷貝與深拷貝

在js中,如果乙個物件,作為變數賦值給另乙個物件,那麼兩個物件得值會是相同得引用位址,其中乙個改變,另外乙個也會隨之改變。var obj1 var obj2 obj1 obj2.num 456 console.log obj1.num 輸出 456 複製 在我們日常開發過程當中,我們去複製乙個物件得...

js深拷貝與淺拷貝

1 基礎知識 基本型別與引用型別 js中可以把變數分成兩部分,基本型別和引用型別。基本型別包括 undefined null boolean number和string 引用型別值可能由多個值構成的物件。在對基礎型別資料進行拷貝時,實際相當於建立新的相同資料 hello 賦值給b var a hel...

js 淺拷貝與深拷貝

js 有兩種資料型別,基礎資料型別和引用資料型別 基礎資料型別都是按值訪問的,我們可以直接操作儲存在變數中的實際的值。而引用型別如array,1.淺拷貝 只複製指向某個物件的指標,而不複製物件本身,新舊物件共享一塊記憶體 淺拷貝是指只複製一層物件,當物件的屬性是引用型別時,實質複製的是其引用,當引用...