學了堆疊記憶體空間,應該就理解了什麼叫簡單資料型別存在棧記憶體,複雜資料型別存在堆記憶體了。
然後面試中經常會問、業務中也經常會遇到的問題就是深淺拷貝的問題了。
棧記憶體中簡單資料型別直接拷貝就能得到乙個副本,但是複雜資料型別的拷貝如果也想得到乙個副本,就需要深拷貝了。
var a = 1;這就是淺拷貝了,雖然你視覺上看上去a = b;但是修改b的值,a不會收影響。因為b是a的乙個副本,就像你拷貝了乙個資料夾副本一樣。修改副本,源資料夾不會受影響。var 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,淺拷貝 拷貝一層物件。深...