目錄
- 淺拷貝
- 拷貝物件
- 使用for in回圈實作
- 使用assign實作
- 使用擴展運算子實作
- 使用JSON物件拷貝
- 拷貝陣列
- 使用slice或concat拷貝
- 使用for遍歷實作也行 跟物件的內容差不多
- 深拷貝
- 使用constructor判斷
- 使用Object.prototypy.toString.call()判斷
- 使用Array.isArray()判斷
- 總結
淺拷貝
拷貝物件
使用for in回圈實作
測驗物件: obj(源), obj2(目標)
let obj = {
a:"1",
b:"man",
func:function(){
console.log("測驗");
},
ob:{
ab:"第二層",
sex:"women"
},
c:[],
arr:[1,23,4,"str",{name:"陣列里面的測驗物件"}
}
let obj2 = {};
簡單實作
for(let prop in obj){
obj2[prop] = obj[prop];
}
使用assign實作
Object.assign(obj2,obj);
使用擴展運算子實作
obj2 = {obj};
使用JSON物件拷貝
let tmp = JSON.stringify(obj);
obj2 = JSON.parse(tmp);
拷貝陣列
使用slice或concat拷貝
測驗用例 arr1(源), arr2(目標)
let arr1 = ["a",1,{name:"第二層",arrDeep:[1,23,5,7]}];
let arr2 = [];
arr2 = arr1.slice();
arr2 = arr1.concat();
//結果回傳的是新的參考 ,但是內容第二層會變為arr1的參考
["a", 1, {name:"第二層",arrDeep:[1,23,5,7]}]
使用for遍歷實作也行 跟物件的內容差不多
深拷貝
使用constructor判斷
測驗物件: obj(源), obj2(目標)
let obj = {
a:"1",
b:"man",
func:function(){
console.log("測驗");
},
ob:{
ab:"第二層",
sex:"women"
},
c:[],
arr:[1,23,4,"str",{name:"陣列里面的測驗物件"}
}
let obj2 = {};
代碼測驗及結果
function deepClone(origin){
let target = origin.constructor === Array? []:{};//判斷復制源為什么型別
for(let prop in origin){
if(origin.hasOwnProperty(prop)){//是否為原型鏈上的屬性
if(typeof origin[prop] == "object"){//判斷是否為基本資料型別
origin[prop].constructor === Array ? target[prop] = []:target[prop] = {};
target[prop] = deepClone(origin[prop]);//為參考資料型別 深層拷貝 遞回呼叫自身
}else{
target[prop] = origin[prop];//正常復制
}
}
}
return target;
}
obj2 = deepClone(obj);

使用Object.prototypy.toString.call()判斷
代碼測驗及結果
function deepClone(origin){
let toStr = Object.prototype.toString;//保存函式參考
let arrayStr = "[object Array]"; //儲存呼叫函式判斷為陣列時回傳的值
let target = toStr.call(origin) == arrayStr? []:{};//判斷復制源為什么型別
for(let prop in origin){
if(origin.hasOwnProperty(prop)){//是否為原型鏈上的屬性
if(typeof origin[prop] == "object"){//判斷是否為基本資料型別
toStr.call(origin[prop]) == arrayStr ? target[prop] = []:target[prop] = {};
target[prop] = deepClone(origin[prop]);//為參考資料型別 深層拷貝 遞回呼叫自身
}else{
target[prop] = origin[prop];//正常復制
}
}
}
return target;
}
obj2 = deepClone(obj);

使用Array.isArray()判斷
代碼測驗及結果
function deepClone(origin){
let target = Array.isArray(origin)? []:{};//判斷復制源為什么型別
for(let prop in origin){
if(origin.hasOwnProperty(prop)){
if(typeof origin[prop] == "object"){//判斷是否為基本資料型別
Array.isArray(origin[prop]) ? target[prop] = []:target[prop] = {};
target[prop] = deepClone(origin[prop]);//為參考資料型別 深層拷貝 遞回呼叫自身
}else{
target[prop] = origin[prop];//正常復制
}
}
}
return target;
}
obj2 = deepClone(obj);
結果

總結
深度拷貝分為一下幾步:
- 判斷復制目標為陣列還是物件
- 回圈遍歷屬性(注意排除原型鏈上的屬性)
- 先用typeof判斷是否為基本屬性
- 若是則直接復制
- 若不是 則使用函式判斷為陣列或者為物件,分別賦值并遞回呼叫自身
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/212642.html
標籤:其他
上一篇:BGP協議實驗(華為)
