Алгоритм структурированного клонирования
Алгоритм структурированного клонирования — это новый алгоритм, определённый спецификацией 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;
}