Что такое 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, циклических ссылок

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

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

TypeScript с нуля

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

Feature-Sliced Design

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

Next.js - с нуля

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