Cloning in JavaScript

javascript; clone
424 words

Cloning in JavaScript

1. Shallow Copy Champions: Object.assign() and Spread Operator ...

These two are the stars of the shallow copy world. They're fast, simple, and have super elegant syntax.

const original = { name: 'Tom', age: 18 };
const copy1 = Object.assign({}, original);
const copy2 = { ...original };

Pros:

  • Simple to use, one line of code
  • Good performance, fast execution

Cons:

  • Only copies one level, fails with nested objects
  • For reference types, copies the reference, not the actual value

Use cases: When you only need to copy simple objects without nested structures, these are your best choices.

2. Deep Copy Veteran: JSON.parse(JSON.stringify())

This method is like the "old-timer" of the deep copy world—a bit clunky, but it works pretty well.

const original = { name: 'Tom', hobbies: ['reading', 'swimming'] };
const copy = JSON.parse(JSON.stringify(original));

Pros:

  • Can handle nested objects
  • Simple implementation, no extra libraries needed

Cons:

  • Poor performance, especially with large objects
  • Cannot handle functions, undefined, Symbol, and other special types
  • Loses prototype chain

Use cases: When you need a quick deep copy implementation and the object structure isn't too complex.

3. Deep Copy Rising Star: structuredClone()

This is the new star of the deep copy world, arriving with modern equipment. structuredClone() is a relatively new global JavaScript method specifically designed for creating deep copies. It became part of the ECMAScript standard in 2022 and is now widely supported in modern browsers and Node.js.

const original = { name: 'Tom', hobbies: ['reading', 'swimming'] };
const copy = structuredClone(original);

Pros:

  • Can handle circular references
  • Supports most data types, including Map, Set, etc.
  • Usually better performance than JSON method

Cons:

  • Doesn't support function cloning
  • May not be supported in older browsers

Use cases: When you need to clone complex objects and don't need to clone functions, this is your best choice.

4. All-Rounder: Custom Deep Clone Function

If you want complete control, roll up your sleeves and do it yourself!

function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(deepClone);
  }

  return Object.fromEntries(
    Object.entries(obj).map(([key, value]) => [key, deepClone(value)])
  );
}

Pros:

  • Complete control over the cloning process
  • Can handle various special cases

Cons:

  • Complex implementation, need to consider many edge cases
  • May have bugs, requires thorough testing

Use cases: When you need to handle special requirements or other methods can't meet your needs.

Summary

  • For cloning simple objects, the spread operator or Object.assign() is enough.
  • Need deep copy without overthinking? structuredClone() is your friend.
  • Objects with functions or other special types? You might need a custom function or third-party library.
  • JSON.parse(JSON.stringify()) is a bit clunky, but still useful in simple scenarios.

Remember, there's no perfect method—choose the one that best fits your current needs. Programming is like cooking: you choose your cooking method based on your ingredients (data) and taste (requirements).