js庫 淺拷貝 深拷貝

2022-01-11 19:00:59 字數 2573 閱讀 1401

學了堆疊記憶體空間,應該就理解了什麼叫簡單資料型別存在棧記憶體,複雜資料型別存在堆記憶體了。

然後面試中經常會問、業務中也經常會遇到的問題就是深淺拷貝的問題了。

棧記憶體中簡單資料型別直接拷貝就能得到乙個副本,但是複雜資料型別的拷貝如果也想得到乙個副本,就需要深拷貝了。

var  a = 1;

var b = a;

這就是淺拷貝了,雖然你視覺上看上去a = b;但是修改b的值,a不會收影響。因為b是a的乙個副本,就像你拷貝了乙個資料夾副本一樣。修改副本,源資料夾不會受影響。

但這種拷貝情況只侷限在簡單型別的拷貝:

string、number、boolean、null、undefiend

如果你拷貝乙個陣列/物件(以陣列為例):

c也被改變了。

但是如果你改變d的整個資料,讓他等於乙個新的陣列(甚至物件)c這時返倒不受影響了。

很奇怪很費解吧?

這是因為:

陣列、物件這類複雜型別資料結構,在棧記憶體裡存放的只是指向堆記憶體中存放資料的位址,

你直接d = c; 拷貝的也是乙個副本,但這個副本區別之處是,他並非資料的副本,而是棧記憶體位址的副本。

這個副本d的位址改變,對c沒有影響,而你給d重新指向乙個新的陣列,就是改變位址了。此時只有d指向了新陣列[5,6,7],但是c不受影響,所以列印出來的不變。

但是雖然有兩個位址,乙個是原、乙個是副本。可他們同時指向同乙個堆記憶體的資料。

這樣看來,你拷貝出來的d和c用的是同乙個陣列。

所以d.push執行以後,並不是c也跟著push了,而是c指向的陣列和被d.push的是同乙個陣列。

你可以想象成,同乙個房間,d和c都拿著鑰匙,這倆鑰匙是不同的,但是他們都是同一間屋子的鑰匙。d用鑰匙開啟門往屋子裡放了乙個東西。那麼c開啟這個屋子,這個東西也還會在。

以上這些,就是基礎知識的解讀。

具體深拷貝就是要理解了複雜型別拷貝的缺點,然後再進行彌補。

既然想要複雜型別也像簡單型別那樣拷貝乙個新資料的話,就不單單是拷貝位址了。而是要重新建立乙個新資料存放空間,然後挨個把想要拷貝的東西搬進來才行。

所以拷貝前我們得判斷乙個資料他到底是什麼型別的,好「對症下藥」:

gettype: function (target)  target: 要獲取型別的變數名或物件

* @output result || "null": 返回的引數 - result或者null,為字串形式的

*/if (target === null)

let result = typeof (target);

if (result == "object") else if (target instanceof object) else

}} console.log("gettype型別判斷為: " + result)

return result; //返回型別值的字串形式

}

以上**,判斷乙個值的型別,輸入值本身,返回字串形式的型別描述。

如果是簡單型別,返回typeof方法返回的對應值即可。

這裡特殊處理了null,因為他用typeof返回object。

然後對於複雜型別的資料,再深入判斷其實array型別還是object型別。

對object型別中,還有構造類需要區分。直接返回[object string]這樣型別的。但其實在深拷貝階段,直接將其放到object形式處理了。

然後就是深拷貝的**:

deepclone: function (origin)  origin: 要轉殖的物件變數名

* @output 根據origin的型別返回的具體值

*/let type = this.gettype(origin),

target;

if (type == "array") );

} else if (type == "object") ;

for (const key in origin)

}} else if (type == "function") ;

target = origin;

} else

return target;

}

對於簡單型別,直接進行拷貝

對於函式,新建乙個function,然後拷貝

對於陣列,新建乙個陣列,然後 foreach 遍歷拷貝。如果迴圈過程中,陣列中巢狀複雜型別,再次遞迴呼叫深拷貝方法。

對於物件,新建乙個物件,然後for in遍歷拷貝非原型值。如果迴圈過程中,物件中巢狀複雜型別,再次遞迴呼叫深拷貝方法。

以上,就是整個邏輯。

宣告:博主:xing.org1^

出處:

js淺拷貝深拷貝

js淺拷貝深拷貝 對於想要複製的物件,如果物件裡面對應的值都是基本資料型別的,可以直接複製 也就是通過淺拷貝複製。如果對應的值有物件那麼淺拷貝是行不通的。會造成資料汙染。下面介紹淺拷貝與深拷貝實現方法。1.淺拷貝 let tem let copy for let key in tem 2.通過obj...

淺拷貝,深拷貝 js

堆和棧 基本型別 存放在棧中的簡單資料段,資料大小確定,記憶體空間大小可以分配。6種基本資料型別 undefined null boolean number和string,es6新增屬性symbol.他們是直接按值存放的,所以可以直接訪問。引用型別 存放在堆記憶體中的物件,變數實際儲存的是乙個指標,...

JS淺拷貝 深拷貝

1,前景提要 1 數字在被複製後,再修改時,不會改變原值 var a 5 var b a b 7 console.log a a不變 2 物件在被複製後,再修改時,會改變原值 var a var b a b.name hi console.log a a.name hi 2,淺拷貝 拷貝一層物件。深...