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


¥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 Uint8Arrays 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: { }