利用 MessageChannel 来实现深克隆

利用 MessageChannel 来实现深克隆

小小孩
2022-12-26 / 0 评论 / 257 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年12月26日,已超过486天没有更新,若内容或图片失效,请留言反馈。

前言

一般 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

评论 (0)

取消