- 使用递归进行深拷贝
function cloneDeep(data) {
//string,number,bool,null,undefined,symbol
//object,array,date
if (data && typeof data === "object") {
//针对函数的拷贝
if (typeof data === "function") {
let tempFunc = data.bind(null);
tempFunc.prototype = cloneDeep(data.prototype);
return tempFunc;
}
// 根据不同的数据类型的深拷贝
switch (Object.prototype.toString.call(data)) {
case "[object String]":
return data.toString();
case "[object Number]":
return Number(data.toString());
case "[object Boolean]":
return new Boolean(data.toString());
case "[object Date]":
return new Date(data.getTime());
case "[object Array]":
var arr = [];
for (let i = 0; i < data.length; i++) {
arr[i] = cloneDeep(data[i]);
}
return arr;
//js自带对象或用户自定义类实例
case "[object Object]":
var obj = {};
for (let key in data) {
//会遍历原型链上的属性方法,可以用hasOwnProperty来控制 (obj.hasOwnProperty(prop)
obj[key] = cloneDeep(data[key]);
}
return obj;
}
} else {
//string,number,bool,null,undefined,symbol
return data;
}
}
- 使用MessageChannel 进行消息通道处理深拷贝
//传递一个字符串
const { port1, port2 } = new MessageChannel();
port1.postMessage('hello')
port2.onmessage = (e) => {
console.log(e.data) // hello
}
//传递一个函数,实现深拷贝
const { port1, port2 } = new MessageChannel();
const obj = {
a: 1,
b: {
c: 2
}
}
port1.postMessage(obj)
port2.onmessage = (e) => {
console.log(e.data) // {a: 1, b: {c: 2}}
console.log(e.data === obj) // false 深拷贝
}
// 封装成一个函数
function deepClone(obj) {
return new Promise(resolve => {
const { port1, port2 } = new MessageChannel();
port1.postMessage(obj);
port2.onmessage = ev => resolve(ev.data);
});
}
port1发送的由port2接收,port2发送的由port1接收。
也就是说,传过去的对象,接收到的时候已经不是原来的引用和指针了,这个时候再return出来,就是一个新的对象。