javascriptobjectclone

What is the most efficient way to deep clone an object in JavaScript?


What is the most efficient way to clone a JavaScript object? I've seen obj = eval(uneval(o)); being used, but that's non-standard and only supported by Firefox.

I've done things like obj = JSON.parse(JSON.stringify(o)); but question the efficiency.

I've also seen recursive copying functions with various flaws.
I'm surprised no canonical solution exists.


Solution

  • Native deep cloning

    There's now a structuredClone(value) function supported in all major browsers and node >= 17. It has polyfills for older systems.

    structuredClone(value)
    

    If needed, loading the polyfill first:

    import structuredClone from '@ungap/structured-clone';
    

    See this answer for more details, but note these limitations:

    Older answers

    Fast cloning with data loss - JSON.parse/stringify

    If you do not use Dates, functions, undefined, Infinity, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays or other complex types within your object, a very simple one liner to deep clone an object is:

    JSON.parse(JSON.stringify(object))

    const a = {
      string: 'string',
      number: 123,
      bool: false,
      nul: null,
      date: new Date(),  // stringified
      undef: undefined,  // lost
      inf: Infinity,  // forced to 'null'
      re: /.*/,  // lost
    }
    console.log(a);
    console.log(typeof a.date);  // Date object
    const clone = JSON.parse(JSON.stringify(a));
    console.log(clone);
    console.log(typeof clone.date);  // result of .toISOString()

    See Corban's answer for benchmarks.

    Reliable cloning using a library

    Since cloning objects is not trivial (complex types, circular references, function etc.), most major libraries provide function to clone objects. Don't reinvent the wheel - if you're already using a library, check if it has an object cloning function. For example,