Skip to content

Copying objects — spread, Object.assign and structuredClone

Level: 201 · for anyone who has changed a copy and seen the original change

Stub — an outline, not a lesson. There is no runnable example behind this page yet, so nothing on it has been through the check that backs every other claim in this library. The questions below are what the finished page has to answer.

One line: Spread and Object.assign copy one level, so nested objects stay shared with the original; structuredClone copies all the way down and keeps Date, Map and even cycles, but throws on a function and hands back a class instance as a plain object.

Keywords: structuredClone, Object.assign

What the finished page will answer

  • After const copy = { ...original }, which changes to copy show up in original: a top-level number, a nested array, a nested object?
  • How do spread and Object.assign differ: which one runs setters on the target, and do either copy symbol keys or non-enumerable properties?
  • What does structuredClone keep that JSON.parse(JSON.stringify(x)) loses: Date, Map, Set, undefined, NaN, a cycle?
  • What does structuredClone throw on, and what happens to a class instance's prototype, methods and #private fields?
  • Why does tsc type structuredClone(new Point(-3)) as a Point, and what happens when you call one of its methods?

Examples it will need

  • copying_objects_shallow_js.js — a nested object copied by spread, Object.assign and structuredClone, then changed through the original, showing which copies change with it
  • copying_objects_clone_limits_js.js — what structuredClone keeps (Date, Map, a cycle), what it throws on (a function, DataCloneError) and what it drops (a class instance's prototype)
  • copying_objects_clone_type_ts.ts — structuredClone of a class instance, which tsc types as the class, and the TypeError caught when the copy's method is called

See also

Sources to start from