堆和棧
棧(stack)為自動(dòng)分配內(nèi)存空間,它由系統(tǒng)自動(dòng)釋放。堆(heap)則是動(dòng)態(tài)分配內(nèi)存,大小不定也不會(huì)自動(dòng)釋放
數(shù)據(jù)類型
- 基本數(shù)據(jù)類型:Boolean, String, Number, undefined, null, Symbol
保存在棧中 - 引用類型:Object
數(shù)據(jù)保存在堆中, 指針保存在棧中
淺拷貝
對象只會(huì)被克隆最外部的一層,對于子對象,依然通過引用指向同一塊堆內(nèi)存
- Object.assign方式
Object.assign(target, source1, source2) - for...in...
function shallowClone (obj) {
const cloneObj = {}
for (let i in obj) {
cloneObj[i] = obj[i]
}
return cloneObj
}
深拷貝
-
JSON.parse(JSON.stringify(obj))
JSON.parse(JSON.stringify(obj)拷貝
我們可以看到,obj和arr正??截悾莇ate變成了字符串,reg變成了空對象,fun直接不見了。所以該方法只能拷貝一些簡單的對象,不適合復(fù)雜對象的拷貝。
- for...in...加遞歸
const isObj = (obj) => (typeof obj === 'object' || typeof obj === 'function') && obj !== null
function deepClone(obj) {
const tempObj = Array.isArray(obj) ? [] : {}
for (let i in obj) {
tempObj[i] = isObj(obj[i]) ? deepClone(obj[i]) : obj[i]
}
return tempObj
}
拷貝的結(jié)果是:

for..in加遞歸拷貝的結(jié)果
我們看到此時(shí)date、fun、reg都變成了空對象
- 環(huán)
環(huán)就是對象循環(huán)引用,導(dǎo)致自己成為一個(gè)閉環(huán)
如:
閉環(huán)
對閉環(huán)進(jìn)行拷貝時(shí)報(bào)錯(cuò):
爆棧
可以使用WeakMap結(jié)構(gòu)存儲(chǔ)被保存的對象,每一次被拷貝時(shí)就先向WeakMap查詢。
function deepClone(obj, map = new WeakMap()) {
if (map.has(obj)) {
return has.get(obj)
}
const tempObj = Array.isArray(obj) ? [] : {}
map.set(obj, tempObj)
for (let i in obj) {
tempObj[i] = isObj(obj[i]) ? deepClone(obj[i]) : obj[i]
}
return tempObj
}
- 結(jié)合以上,解決Date、RegExp、Function的深拷貝如下
function deepClone (obj, map = new WeakMap()) {
let cloneObj
let Constructor = obj.constructor
switch (Constructor) {
case Date:
cloneObj = new Constructor(obj.getTime())
break
case RegExp:
cloneObj = new Constructor(obj)
break
case Function:
cloneObj = function () {
const temp = function temporary() { return this.apply(obj, arguments) }
for( let key in obj ) {
if (obj.hasOwnProperty(key)) {
temp[key] = obj[key]
}
}
return temp
}
break
default:
if (map.has(obj)) {
return map.get(obj)
}
cloneObj = new Constructor()
map.set(obj, cloneObj)
break;
}
for (const key in obj) {
cloneObj[key] = isObj[obj[key]] ? deepClone(obj[key]) : obj[key]
}
return cloneObj
}

拷貝結(jié)果


