Skip to content

Commit

Permalink
doc: add note about uncloneable objects
Browse files Browse the repository at this point in the history
Signed-off-by: James M Snell <jasnell@gmail.com>

PR-URL: #36534
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
  • Loading branch information
jasnell authored and danielleadams committed Jan 12, 2021
1 parent f0a9c53 commit edf8c6d
Showing 1 changed file with 43 additions and 5 deletions.
48 changes: 43 additions & 5 deletions doc/api/worker_threads.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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()`
<!-- YAML
added: v10.5.0
Expand Down

0 comments on commit edf8c6d

Please sign in to comment.