數(shù)組淺拷貝
1.原始循環(huán)放入新數(shù)組
2.arr.slice()
返回新數(shù)組
3.arr.concat()
返回新數(shù)組
4.[...arr]
擴展運算符
以上方法只能淺拷貝一維數(shù)組启具、(含對象的數(shù)組只能拷貝到對象的引用地址)
對象淺拷貝
淺拷貝之所以被稱為淺拷貝,是因為對象只會被克隆最外部的一層,至于更深層的對象,則依然是通過引用指向同一塊堆內(nèi)存.
[...obj]
擴展運算符 淺拷貝
Object.assign
是淺拷貝
var a={
obj:{a:'name'}
}
var c=Object.assign({},a)
c.obj.a='name111';
console.log(a) //{"obj":{"a":"name111"}}
深拷貝 數(shù)組珊泳、對象值包含引用類型值的時候
JSON.parse( JSON.stringify())
;
這種簡單粗暴的方法有其局限性鲁冯。當值為undefined
、function
色查、symbol
會在轉(zhuǎn)換過程中被忽略薯演。。秧了。所以跨扮,對象值有這三種的話用這種方法會導致屬性丟失。
存在的坑:
1.他無法實現(xiàn)對函數(shù) 验毡、RegExp等特殊對象的克隆
2.會拋棄對象的constructor,所有的構(gòu)造函數(shù)會指向Object
3.對象有循環(huán)引用,會報錯
var arr = ['old', 1, true, ['a1', 'a2'], {num: 1}]
var new_arr = JSON.parse( JSON.stringify(arr) );
手寫數(shù)組和對象 拷貝
淺拷貝
var shallowCopy = function(obj) {
// 只拷貝對象
if (typeof obj !== 'object') return obj;
// 根據(jù)obj的類型判斷是新建一個數(shù)組還是對象
var newObj = obj instanceof Array ? [] : {};
// 遍歷obj衡创,并且判斷是obj的屬性才拷貝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
深拷貝方法
盡管使用深拷貝會完全的克隆一個新對象,不會產(chǎn)生副作用米罚,但是深拷貝因為使用遞歸钧汹,性能會不如淺拷貝丈探,在開發(fā)中录择,還是要根據(jù)實際情況進行選擇。
function deepCopy(obj) {
if (typeof obj == "object") {
//復雜數(shù)據(jù)類型
var result= Array.isArray(obj) ? [] : {};
for (let i in obj) {
result[i] = typeof obj[i] == "object" ? deepCopy(obj[i]) : obj[i];
}
return result;
} else {
//簡單數(shù)據(jù)類型 直接賦值
return obj;
}
}