From edf8c6de5a1ab9d540963bae7826ec7d00d06ec8 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 15 Dec 2020 10:57:33 -0800 Subject: [PATCH] doc: add note about uncloneable objects Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/36534 Reviewed-By: Anna Henningsen Reviewed-By: Benjamin Gruenbaum Reviewed-By: Luigi Pinca Reviewed-By: Rich Trott Reviewed-By: Franziska Hinkelmann --- doc/api/worker_threads.md | 48 +++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index 2f46c6ef1a14ef..f32c2c4cf5ecf1 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -547,11 +547,6 @@ const otherChannel = new MessageChannel(); port2.postMessage({ port: otherChannel.port1 }, [ otherChannel.port1 ]); ``` -Because the object cloning uses the structured clone algorithm, -non-enumerable properties, property accessors, and object prototypes are -not preserved. In particular, [`Buffer`][] objects are read as -plain [`Uint8Array`][]s on the receiving side. - The message object is cloned immediately, and can be modified after posting without having side effects. @@ -606,6 +601,49 @@ The `ArrayBuffer`s for `Buffer` instances created using transferred but doing so renders all other existing views of those `ArrayBuffer`s unusable. +#### Considerations when cloning objects with prototypes, classes, and accessors + +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`][]s on the receiving side, and instances of JavaScript +classes will be cloned as plain JavaScript objects. + +```js +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 } +``` + +This limitation extends to many built-in objects, such as the global `URL` +object: + +```js +const { port1, port2 } = new MessageChannel(); + +port1.onmessage = ({ data }) => console.log(data); + +port2.postMessage(new URL('https://example.org')); + +// Prints: { } +``` + ### `port.ref()`