使用原型、类、以及访问器克隆对象时的注意事项


¥Considerations when cloning objects with prototypes, classes, and accessors

因为对象克隆使用 HTML 结构化克隆算法,所以不保留不可枚举的属性、属性访问器和对象原型。特别是,<Buffer> 对象在接收方将被读取为纯 <Uint8Array>,而 JavaScript 类的实例将被克隆为纯 JavaScript 对象。

¥Because object cloning uses the HTML structured clone algorithm, non-enumerable properties, property accessors, and object prototypes are not preserved. In particular, <Buffer> objects will be read as plain <Uint8Array> on the receiving side, and instances of JavaScript classes will be cloned as plain JavaScript objects.

const b = Symbol('b');

class Foo {
  #a = 1;
  constructor() {
    this[b] = 2;
    this.c = 3;
  }

  get d() { return 4; }
}

const { port1, port2 } = new MessageChannel();

port1.onmessage = ({ data }) => console.log(data);

port2.postMessage(new Foo());

// Prints: { c: 3 } 

此限制扩展到许多内置对象,例如全局的 URL 对象:

¥This limitation extends to many built-in objects, such as the global URL object:

const { port1, port2 } = new MessageChannel();

port1.onmessage = ({ data }) => console.log(data);

port2.postMessage(new URL('https://example.org'));

// Prints: { }