structuredClone with Functions and DOM Nodes
The native JavaScript structuredClone() method creates
deep copies of complex data structures, but it has strict limitations
regarding non-serializable objects. When either functions or DOM nodes
are passed into structuredClone(), the method immediately
throws a DataCloneError DOMException. This article explains
why the structured clone algorithm rejects these values and outlines the
proper alternatives for cloning them.
Passing Functions to structuredClone
JavaScript functions cannot be duplicated by
structuredClone(). If you pass a standalone function or an
object containing a function property into
structuredClone(), execution halts with an error:
// Throws: DOMException: function could not be cloned
structuredClone(() => console.log("hello"));
// Throws: DOMException: function could not be cloned
structuredClone({ name: "Alice", greet: function() {} });Why It Fails
Functions encapsulate executable code, hidden scopes, closures, and internal execution contexts. These characteristics cannot be safely serialized, transferred, or reconstructed in memory across different environments or threads.
Workarounds for Functions
To clone an object that contains methods: 1. Separate Data
from Behavior: Keep data in plain objects and define methods on
a shared prototype, class, or module. 2. Manual
Copying: Copy the data fields with
structuredClone() and reassign the necessary functions
afterward:
javascript const original = { data: [1, 2, 3], run() { return true; } }; const copy = { ...structuredClone({ data: original.data }), run: original.run };
Passing DOM Nodes to structuredClone
Passing any DOM node—such as an HTMLElement,
Document, or TextNode—to
structuredClone() also triggers a
DataCloneError:
const button = document.createElement("button");
// Throws: DOMException: HTMLButtonElement could not be cloned
structuredClone(button);Why It Fails
DOM nodes are live references tied to the browser’s rendering engine and the active document tree. They carry event listeners, internal platform pointers, and contextual state that cannot be represented as serializable data within the structured clone algorithm.
Workarounds for DOM Nodes
To duplicate DOM elements, use the dedicated DOM API method
Node.cloneNode() instead:
const originalElement = document.querySelector("#my-element");
// Create a deep copy of the DOM element and its children
const clonedElement = originalElement.cloneNode(true);Note that cloneNode() duplicates the element’s
attributes and inline HTML structure, but it does not copy event
listeners added via addEventListener(). Those must be
attached to the new node manually.