Алгоритм структурированного клонирования
Алгоритм структурированного клонирования — это новый алгоритм, определённый спецификацией HTML5 для сериализации комплексных JavaScript объектов. Он более функционален, чем JSON в том что способен поддерживать сериализацию объектов содержащих циклические графы — первичные объекты, которые ссылаются на другие объекты у которых есть ссылка на первичные объекты в том же графе. В дополнение, в некоторых других случаях алгоритм структурированного клонирования может быть более эффективен, чем JSON.
Алгоритм, по существу, перебирает все поля оригинального объекта, дублируя значения каждого поля в новый объект. Если поле представляет из себя объект с собственными полями, то эти дочерние поля также перебираются рекурсивно, пока каждое поле и все дочерние поля не будут продублированы в новый объект.
Преимущества перед JSON
Вот основные преимущества структурированного клонирования перед JSON:
- Структурированные клоны могут копировать
RegExp
объекты. - Структурированные клоны могут копировать
Blob
,File
, иFileList
объекты. - Структурированные клоны могут копировать
ImageData
объекты. The dimensions of the clone'sCanvasPixelArray
will match the original and have a duplicate of the same pixel data. - Structured clones can correctly duplicate objects containing cyclic graphs of references.
Исключения, не работающие со структурированными клонами
Error
andFunction
objects cannot be duplicated by the structured clone algorithm; attempting to do so will throw aDATA_CLONE_ERR
exception.Attempting to clone DOM nodes will likewise throw a
DATA_CLONE_ERR
exception.Certain parameters of objects are not preserved:
- The
lastIndex
field ofRegExp
objects is not preserved. - Property descriptors, setters, and getters (as well as similar metadata-like features) are not duplicated. For example, if an object is marked read-only using a property descriptor, it will be read-write in the duplicate, since that's the default condition.
- The prototype chain does not get walked and duplicated.
- The
Поддерживаемые типы
Object type | Notes |
---|---|
All primitive types | However not symbols |
Boolean object | |
String object | |
Date | |
RegExp | The lastIndex field is not preserved. |
Blob | |
File | |
FileList | |
ArrayBuffer | |
ArrayBufferView | This basically means all typed arrays like Int32Array etc. |
ImageData | |
Array | |
Object | This just includes plain objects (e.g. from object literals) |
Map | |
Set |
Другой вариант: вложенное копирование
Если вы хотите сделать вложенную копию объекта (т.е рекурсивно копировать все вложенные свойства, проходя по прототипной цепи), вы должны использовать другой подход. Ниже приведён возможный пример.
function clone(objectToBeCloned) { // Basis. if (!(objectToBeCloned instanceof Object)) { return objectToBeCloned; } var objectClone; // Filter out special objects. var Constructor = objectToBeCloned.constructor; switch (Constructor) { // Implement other special objects here. case RegExp: objectClone = new Constructor(objectToBeCloned); break; case Date: objectClone = new Constructor(objectToBeCloned.getTime()); break; default: objectClone = new Constructor(); } // Clone each property. for (var prop in objectToBeCloned) { objectClone[prop] = clone(objectToBeCloned[prop]); } return objectClone; }