Explain Codes LogoExplain Codes Logo

How can I clone a JavaScript object except for one key?

javascript
clone
object
javascript
Nikita BarsukovbyNikita Barsukov·Nov 11, 2024
TLDR

To clone a JavaScript object and exclude a certain key, destructuring assignment is your best friend:

const { keyToRemove, ...clonedObject } = originalObject;

clonedObject contains all properties from originalObject except keyToRemove.

Deeper diving into cloning and key exclusion

Not all object cloning scenarios are created equal. Let's explore a few patterns based on usage requirements.

Excluding a dynamic key

If the key to exclude isn't a constant, a small adjustment let's us exclude a dynamic key:

let keyToSkip = 'unwantedKey'; // Bad key! Bad! const { [keyToSkip]: _, ...clonedObject } = originalObject; // _ is our inconspicuous buddy Mr. Discardable Variable, helping keep linters happy

Advanced cloning: Nested objects

For more complex nested objects, consider a utility function like deepOmit:

const deepOmit = (obj, unwantedKey) => { return Object.entries(obj).reduce((acc, [key, value]) => { if (key === unwantedKey) return acc; // Ignoring unwanted stuff like a pro acc[key] = value instanceof Object ? deepOmit(value, unwantedKey) : value; return acc; }, {}); }; // Remember, as the famous programmer saying goes, // "With great recursion, comes great responsibility". // This doesn't handle Array or Date instances, so tread carefully.

Resorting to Libraries

When fancy ECMAScript (es6/es7) syntax isn't an option, Lodash or Ramda omit you right out of this mess:

const _ = require('lodash'); const clonedObject = _.omit(originalObject, 'keyToRemove');

Keep an eye out for library overuse though, as the saying goes, "size matters", bundle size that is.

Exploring the broader cloning landscape

Performance tuning: Larger objects

For gigantic objects or performance-intensive applications, the traditional Object.assign() may be more performance-friendly:

const clonedObject = Object.assign({}, originalObject); delete clonedObject[keyToRemove]; // Bye bye keyToRemove!

The curious case of Undefined vs. Delete

Did you know setting a property to undefined does not entirely exorcise the key?

const clonedObject = {...originalObject, [keyToRemove]: undefined}; // keyToRemove is still in the keys list, a ghost lingering in our cloned array!

Little gotchas like these can get you when using Object.keys() or other key enumeration functions.

Addressing edge cases

  • Non-enumerable properties, they're like the ninjas of JavaScript object properties. Cloning them requires fancier tricks like Object.getOwnPropertyNames.
  • Symbol properties, these wily critters aren't copied with Object.assign(). You might have to wrangle them separately.