
未標(biāo)題-1 拷貝.jpg
我們知道,JS 中的數(shù)據(jù)分為基礎(chǔ)數(shù)據(jù)類型 (Undefined, Null, Boolean, Number, String, symbol) 和引用數(shù)據(jù)類型(object)。
當(dāng)賦值給變量進(jìn)行數(shù)據(jù)保存時(shí),前者保存的是數(shù)據(jù)實(shí)體,后者保存的是數(shù)據(jù)實(shí)體在堆內(nèi)存中的地址。
為什么會(huì)這樣?在 JS 中,也有棧內(nèi)存和堆內(nèi)存的概念。
棧,是在程序編譯時(shí)分配,它是連續(xù)的內(nèi)存空間,容量小,系統(tǒng)分配效率高,有后進(jìn)先出的特性,適合存儲(chǔ)簡單有固定尺寸的數(shù)據(jù),如基礎(chǔ)數(shù)據(jù)。
堆,是在程序運(yùn)行時(shí)申請的某個(gè)大小的內(nèi)存空間,不連續(xù),樹形結(jié)構(gòu)。容量大,系統(tǒng)分配效率略低,適合存儲(chǔ)尺寸不確定的數(shù)據(jù),如 Object。
基礎(chǔ)數(shù)據(jù)的存儲(chǔ)是系統(tǒng)直接在棧內(nèi)存中開出一塊空間存值,而 Object 的存儲(chǔ),是先在堆內(nèi)存中開辟空間存值,然后在棧內(nèi)存中存址。
本質(zhì)區(qū)別
深拷貝和淺拷貝的本質(zhì)區(qū)別在于對引用類型數(shù)據(jù)的拷貝,前者拷值,后者拷址。
本文所述的拷貝主要是對象和數(shù)組的拷貝。
代碼實(shí)現(xiàn)
// data type
const whatType = obj => Object.prototype.toString.call(obj).slice(8, -1)
// shallow copy
function shallowCopy(obj) {
let result;
switch (whatType(obj)) {
case "object":
result = {};
break;
case "Array":
result = [];
break;
default:
return obj
}
for (key in obj) {
obj[key] = obj[key]
}
return result
}
// deep copy
const deepCopy = (function f(obj) {
let result;
switch (whatType(obj)) {
case "Object":
result = {};
break;
case "Array":
result = [];
break;
default:
return obj
}
for (key in obj) {
const type = whatType(obj[key])
if ( type=== "Object" || type === "Array") {
result[key] = f(obj[key])
} else {
result[key] = obj[key]
}
}
return result
})
// 深拷貝的另一種簡便方式
const deepCopy2 = obj => JSON.parse(JSON.stringfy(obj))