原生js實現深拷貝函式
阿新 • • 發佈:2019-02-06
首先實現一個函式對變數型別進行判斷
// 判斷變數的型別 function getType(obj){ var str = Object.prototype.toString.call(obj); var map={ '[object Boolean]' : 'boolean', '[object Number]' : 'number', '[object String]' : 'string', '[object Function]' : 'function', '[object Array]' : 'array', '[object Date]' : 'date', '[object RegExp]' : 'regExp', '[object Undefined]': 'undefined', '[object Null]' : 'null', '[object Object]' : 'object' } if(obj instanceof Element){ //判斷是否是dom元素,如div等 return "element"; } return map[str]; }
下面我們實現deepCopy函式,對物件中的陣列或物件進行遞迴呼叫拆分複製,讓兩個物件中的陣列或
物件相互獨立
//深拷貝函式 function deepCopy(p){ var obj; var str = getType(p); if(str == 'array'){ obj = []; for (var i = 0; i < p.length; i++) { obj.push(arguments.callee(p[i])); //回撥自己 } }else if(str == 'object'){ obj = {}; for(var i in p){ obj[i] = arguments.callee(p[i]); } }else{ return p; } return obj; }
接下來呼叫測試吧!參考部落格
var a={
color:['red','blue','black'],
age:10,
}
var b = deepCopy(a);
b.color.push('green');
console.log(a);
console.log(b);
特別方法
JSON.parse(JSON.stringify(object))
侷限性:
- 會忽略
undefined
- 不能序列化函式,會被忽略
- 不能解決迴圈引用的物件
更新(2018/8/7):
MessageChannel
MessageChannel建立訊息通道,傳遞訊息使用的是深拷貝
侷限性:
- 非同步深拷貝,有時我們需要同步深拷貝
const MessageClone = (obj) => {
return new Promise(resolve => {
const {
port1,
port2
} = new MessageChannel();
port2.onmessage = mes => resolve(mes.data);
port1.postMessage(obj);
});
}
let obj = {
a: {
b: 1,
arr: [1, 2, 3, 4]
}
},
newObj = null;
MessageClone(obj).then(obj => {
newObj = obj;
console.log(newObj);
});