前言
一般 JS 深度克隆有两种方法 ,一种是 JSON
序列与反序列,另一种是 lodash
提供的 deepClone
,
其中利用 JSON 克隆 有以下缺点
- 属性值为函数和 undefined 的属性会丢失
- 属性值为正则表达式的会变成{}
- 属性值为时间对象的会变成时间字符串
其实另一种方法来实现克隆,利用MessageChannel
消息通道的数据传输也可以实现对象深拷贝。
MessageChannel
利用 MessageChannel() 构造函数返回一个新的 MessageChannel 对象,其中返回的对象中包含两个 MessagePort 对象。这就是两个通道,其中可以数据传输。
具体实现如下:
function deepClone(obj) {
return new Promise((resolve, reject) => {
const { port1, port2 } = new MessageChannel();
port1.postMessage(obj);
port2.onmessage = (msg) => {
resolve(msg.data);
};
port2.onerror = (msg) => {
reject(msg.data);
};
});
}
使用
(async () => {
function deepClone(obj) {
return new Promise((resolve, reject) => {
const { port1, port2 } = new MessageChannel();
port1.postMessage(obj);
port2.onmessage = (msg) => {
resolve(msg.data);
};
port2.onerror = (msg) => {
reject(msg.data);
};
});
}
const obj = {
a: 1,
b: /\d/,
c: new Date(),
d: undefined,
};
const cloneObj = await deepClone(obj);
console.log(cloneObj, cloneObj === obj);
})();
利用 MessageChannel 来实现克隆 可以解决 大部分 JSON 克隆的缺点,但还是有个缺点是函数不能拷贝。
如果你所需拷贝的对象含有内置类型并且不包含函数,就可以利用 MessageChannel 来实现克隆。
如果函数也要拷贝, 还是使用lodash
通过递归处理的 deepClone
方法。
评论 (0)