Explain Codes LogoExplain Codes Logo

How to duplicate object properties in another object?

javascript
deep-copying
shallow-copying
object-cloning
Alex KataevbyAlex Kataev·Feb 17, 2025
TLDR

To duplicate object properties swiftly, you can utilize the spread operator ...:

const original = { a: 1, b: 2 }; // Trying to make more `original` jokes in comments ;) let duplicate = { ...original };

Alternatively, you can use the Object.assign() method for an immediate duplication:

// Operation clone is a success! let duplicate = Object.assign({}, original);

Both methods create a new object that has the identical properties as the original object.

Differentiating between shallow and deep copying

Understanding the concept of shallow and deep copying is vital when duplicating objects. A shallow copy duplicates an object's top-level properties, while a deep copy duplicates the entire object, including nested objects.

Here is how to perform a shallow copy:

// Shallow clone: just the surface const shallowDuplicate = { ...original };

For a deep copy, you can use JSON.stringify() coupled with JSON.parse():

// Deep clone: digging all layers of the object const deepDuplicate = JSON.parse(JSON.stringify(original));

N.B. This deep copy technique doesn’t support circular references, functions, and certain special objects like Date, RegExp, Map and Set.

Ensuring that you’re duplicating owned properties

When duplicating properties with a for...in loop, use .hasOwnProperty to avoid copying inherited properties:

for (const key in original) { if (original.hasOwnProperty(key)) { duplicate[key] = original[key]; } }

Supporting both older and modern browsers

If you're supporting modern browsers, ES6 features like Object.assign() and the spread operator are up to the task:

// The modern way with spread syntax const newDuplicate = { ...original }; // Or a more 'traditional' approach with Object.assign const newDuplicate2 = Object.assign({}, original);

For older browsers, you may need polyfills or a transpiler such as Babel to utilize ES6 features. Alternatively, you can resort to ES5 syntax for better compatibility.

Creating custom functions for unique situations

In certain scenarios, native copying methods might not suffice. Creating custom functions gives you more control, allowing you to handle complex object structures and avoid shared references:

function customClone(object) { // Your genius custom implementation goes here }

Remember, always test your implementation to ensure that the cloning behavior meets your application's requirements.

Checking browser compatibility before you roll

Before using some of your favorite advanced JavaScript bells and whistles, do confirm their browser compatibility. Check out JavaScript compatibility tables like Kangax's compat-table for a quick reference on browser support.

Opting for native methods over frameworks

Before reaching for libraries or frameworks, consider using native JavaScript methods. Modern JavaScript provides powerful primitives and intuitive syntax to handle various cases.

  • Shallow duplication: Use Object.assign() or spread {...object}.
  • Deep duplication: Write a custom function or use JSON.stringify and JSON.parse().
  • Property iteration: Use Object.keys(), Object.values(), or Object.entries() in combination with array methods like forEach() or map().

Benefits of native methods include:

  • Fewer dependencies, which translates to less overhead and easier maintenance.
  • Improved performance, since native operations usually outperform library functions.
  • Simplified debugging, thanks to less complexity and smaller call stacks.

Understanding potential pitfalls

Beware of shared references when clones lead to unexpected side effects:

const original = { nested: { count: 1 } }; const shallowDuplicate = { ...original }; shallowDuplicate.nested.count = 2; console.log(original.nested.count); // Outputs 2: un-copied object was modified!

Avoid shared references with deep cloning:

const deepDuplicate = JSON.parse(JSON.stringify(original)); deepDuplicate.nested.count = 3; console.log(original.nested.count); // Outputs 1: nested object is safe from manipulation