The structured clone algorithm

The structured clone algorithm is a new algorithm defined by the HTML5 specification for serializing complex JavaScript objects. It's more capable than JSON in that it supports the serialization of objects that contain cyclic graphs — objects can refer to objects that refer to other objects in the same graph. In addition, in some cases, the structured clone algorithm may be more efficient than JSON.

The algorithm, in essence, walks over all the fields of the original object, duplicating the values of each field into a new object. If a field is, itself, an object with fields, those fields are walked over recursively until every field and sub-field is duplicated into the new object.

Benefits over JSON

There are a few key benefits of the structured clone algorithm over JSON:

  • Structured clones can duplicate RegExp objects.
  • Structured clones can duplicate Blob, File, and FileList objects.
  • Structured clones can duplicate ImageData objects. The dimensions of the clone's CanvasPixelArray will match the original and have a duplicate of the same pixel data.
  • Structured clones can correctly duplicate objects containing cyclic graphs of references.

Things that don't work with structured clones

  • 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.

Supported types

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  

Another way: deep copy‎

If you want a deep copy of an object (that is, a recursive copy of all nested properties, walking the prototype chain), you must use another approach. The following is a possible example.

JavaScript
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;
}
  Note: This algorithm actually implements only RegExp, Array, and Date special objects. You can implement other special cases depending on your needs.

See also

License

© 2016 Mozilla Contributors
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-us/docs/web/api/web_workers_api/structured_clone_algorithm

Advanced DOM HTML5 JavaScript Reference Référence