Что такое structuredClone в JavaScript и когда его применять?

MiddleJavaScript · Frontend·Обновлено 29 августа 2026
Коротко
structuredClone — это встроенная функция для глубокого клонирования значений (объектов, массивов, Map, Set, Date и др.) на основе алгоритма structured clone, который используется в postMessage и IndexedDB. Применяется, когда нужен нативный глубокий клон без сторонних библиотек, но она не умеет клонировать функции, DOM-узлы и Symbol.

Что это такое

structuredClone — глобальная функция, доступная в браузерах и в Node.js начиная с 17-й версии, которая выполняет глубокое клонирование значения. В её основе лежит тот же алгоритм structured clone algorithm, что используется движком при передаче данных через postMessage, запись в IndexedDB и обмен сообщениями с Web Worker'ами. До её появления для глубокого копирования приходилось использовать JSON.parse(JSON.stringify(x)) или библиотеки вроде lodash cloneDeep.

const original = { user: { name: 'Аня' }, tags: [1, 2, 3] };
const clone = structuredClone(original);

clone.user.name = 'Боря';
console.log(original.user.name); // 'Аня' — оригинал не затронут
console.log(original === clone); // false
console.log(original.user === clone.user); // false, вложенные объекты тоже скопированы

Что умеет клонировать

  • Обычные объекты и массивы, в том числе вложенные и с циклическими ссылками
  • Map, Set, Date, RegExp
  • ArrayBuffer, TypedArray, DataView
  • Blob, File, ImageData
  • Ошибки (Error) — частично, с потерей некоторых свойств

Чего не умеет

  • Функции — попытка клонировать функцию или объект с методом бросает DataCloneError
  • DOM-узлы
  • Symbol и свойства с ключами-символами
  • Геттеры/сеттеры и дескрипторы свойств — клон получает обычные data-properties
  • Прототипная цепочка кастомных классов — экземпляр класса превращается в обычный объект с Object.prototype
class User {
  constructor(name) { this.name = name; }
  greet() { return `Привет, ${this.name}`; }
}

const u = new User('Аня');
const clonedUser = structuredClone(u);

console.log(clonedUser instanceof User); // false — прототип потерян
console.log(clonedUser.greet); // undefined — метода нет

Когда применять

  • Нужен надёжный глубокий клон данных без подключения lodash
  • Работа с Web Worker'ами — данные всё равно проходят через structured clone при postMessage, поэтому логично использовать тот же механизм явно
  • Снятие снапшота состояния для undo/redo или сравнения до/после мутации
  • Клонирование сложных данных с Date, Map, Set, которые JSON.stringify испортит

Когда не подходит

  • Нужно сохранить методы/прототип класса — тогда лучше писать собственный метод clone() или использовать Object.create
  • Критична производительность на очень больших структурах в горячем пути — стоит измерить и рассмотреть неглубокое копирование через spread, если глубина не нужна
  • Нужно клонировать функции как значения (например, конфиг с колбэками)

Сравнение с альтернативами

JSON.parse(JSON.stringify(x)) — теряет undefined, функции и Symbol, превращает Date в строку, не поддерживает циклические ссылки (кидает ошибку) и Map/Set.

structuredClone — быстрее и поддерживает больше встроенных типов, но всё ещё не про кастомные классы и функции.

structuredClone также принимает опцию transfer для передачи владения ArrayBuffer без копирования — актуально при обмене данными с воркерами.

const buffer = new ArrayBuffer(1024);
const clone = structuredClone({ buffer }, { transfer: [buffer] });
// buffer.byteLength теперь 0 — владение передано, а не скопировано

Что хочет услышать интервьюер

Понимание, что это встроенный способ глубокого клонирования, а не поверхностного (shallow)

Знание ограничений: функции, DOM-узлы, Symbol и прототипы классов не клонируются

Умение сравнить с JSON.parse(JSON.stringify()) и объяснить преимущества (Date, Map, Set, циклические ссылки)

Знание связи structuredClone с postMessage/Web Workers/IndexedDB

Понимание опции transfer для ArrayBuffer

Пример: Базовое глубокое клонирование

const original = {
  createdAt: new Date(),
  tags: new Set(['a', 'b']),
  meta: new Map([['k', 1]]),
};

const clone = structuredClone(original);

console.log(clone.createdAt instanceof Date); // true
console.log(clone.tags instanceof Set); // true
console.log(clone === original); // false

Пример: Ошибка при клонировании функции

try {
  structuredClone({ fn: () => {} });
} catch (e) {
  console.log(e.name); // 'DataCloneError'
}

Пример: Циклические ссылки — не проблема

const a = { name: 'a' };
a.self = a; // циклическая ссылка

const clone = structuredClone(a);
console.log(clone.self === clone); // true, структура сохранена

Типичные ошибки

Утверждают, что structuredClone клонирует функции или методы класса — на самом деле бросается DataCloneError или метод теряется

Путают structuredClone с поверхностным копированием через spread или Object.assign

Не знают, что клон экземпляра класса теряет прототип и становится обычным объектом

Забывают, что это относительно новая функция и может отсутствовать в старых окружениях (нужен полифилл или проверка поддержки)

Считают, что structuredClone эквивалентен JSON.stringify по возможностям, не упоминая поддержку Date, Map, Set, циклических ссылок

Лучшие курсы по теме

изображение курса

Angular

Антон Ларичев
AI-тренажерыAI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Vue 3 и Pinia

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее