Алгоритм структурированного клонирования
========================================

Алгоритм структурированного клонирования — это новый алгоритм, определённый спецификацией HTML5 для сериализации комплексных JavaScript объектов. Он более функционален, чем JSON в том что способен поддерживать сериализацию объектов содержащих циклические графы — первичные объекты, которые ссылаются на другие объекты у которых есть ссылка на первичные объекты в том же графе. В дополнение, в некоторых других случаях алгоритм структурированного клонирования может быть более эффективен, чем JSON.

Алгоритм, по существу, перебирает все поля оригинального объекта, дублируя значения каждого поля в новый объект. Если поле представляет из себя объект с собственными полями, то эти дочерние поля также перебираются рекурсивно, пока каждое поле и все дочерние поля не будут продублированы в новый объект.

Преимущества перед JSON
-----------------------

Вот основные преимущества структурированного клонирования перед JSON:

* Структурированные клоны могут копировать `RegExp` объекты.
* Структурированные клоны могут копировать `Blob`, `File`, и `FileList` объекты.
* Структурированные клоны могут копировать `ImageData` объекты. The dimensions of the clone's `CanvasPixelArray` (en-US) 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` and `Function` objects cannot be duplicated by the structured clone algorithm; attempting to do so will throw a `DATA_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 of `RegExp` 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.
Поддерживаемые типы
-------------------

| 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 (en-US) | This basically means all typed arrays like Int32Array etc. |
| `ImageData` |  |
| Array |  |
| Object | This just includes plain objects (e.g. from object literals) |
| Map (en-US) |  |
| Set |  |

Другой вариант: вложенное копирование‎
--------------------------------------

Если вы хотите сделать вложенную копию объекта (т.е рекурсивно копировать все вложенные свойства, проходя по прототипной цепи), вы должны использовать другой подход. Ниже приведён возможный пример.


```js
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;
}
```


**Примечание:** Этот алгоритм реализован только для `RegExp`, `Array`, и `Date` специальных объектов. Вы можете реализовать другие условия, удовлетворяющие вашим потребностям.

Ещё по теме
-----------

* HTML5 Specification: Safe passing of structured data
* `window.history`
* `window.postMessage()`
* Web Workers
* Components.utils.cloneInto