BlogJavaScript

Copying an object without a property or key in JavaScript

Written by Codemzy on July 27th, 2022

Copying objects in javascript can get complicated if you only want to copy part of an object, or if there is a property or key that you don't need. Instead of copying the entire object and then deleting a property, you can just copy what you need with object destructuring.

This is going to be a fairly short post that shows you how to copy only the properties you want into a new object. If you just want the code, here's the function I use:

let newObject = (({ b, d, ...object }) => object)(originalObject);

With b and d (in this example) being the properties I don't want on the new object.

Read on to see how it works!


Have you ever wanted to create a copy of an object but not entirely? Maybe you want to copy an object without some properties, or even just get rid of one key on your new object? You want most of it, but not all of it!

Say for example you have an object like:

let originalObject = {
  a: "A",
  b: 2,
  c: "C",
  d: 4
};

And you want to create a newObject with just a and c. I’ve had this come up a few times, and for an object with not many keys - like our example object - I’ll often do something like this…

let newObject = { a: originalObject.a, c: originalObject.c };

And that's fine if I only need to copy across a few properties. But what if there's 10+? What if there are 20+? Or more? That seems like a lot of effort!

I really like using object destructuring to create a copy of an object. You can simply copy across all of the contents of an object, without having to write it out or use a function.

let newObject = { ...originalObject };

I don't know why, but there's something about those 3 little dots that I find very satisfying. I know there's Object.assign() but I have to remember what order to put things in and that usually involves a quick trip to MDN. With ... I don't have to remember any functions or the order of arguments. Just drop in the 3 dots and you're done.

Whichever way you prefer to create a copy of an object, with both destructuring and Object.assign() you copy over the entire originalObject to the newObject. If there's a key you don't want, you would need to delete it afterwards.

delete newObject.b;

But in some circumstances, deleting the key afterwards doesn't work well. Or it's going to add extra complexity to your code. And again, what if there are 10+ properties you need to delete? Wouldn't it be simpler to only copy over the values from the object you need in the first place?

You can kinda do this with destructuring out of the box, by unpacking the properties you don't want (which is what destructuring let's us do).

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

- MDN Destructuring assignment
let { b, d, ...newObject } = { ...originalObject };

But now the b and d keys have become variables polluting the global namespace. If we don't want them there, it doesn't feel right to do that. We've moved the problem of copying them over to the new object, to copying them to global variables instead!

Can't they just not come across from the original object at all? We don't want you b and d - take a hint!

While it's not possible to do this with destructuring alone, you can achieve it by destructuring the object through a function and returning only the properties you need. Since this is a throwaway function that I won't re-use, and I want to use it straight away, an immediately invoked function expression (IIFE) is my weapon of choice.

An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.

- MDN IIFE

Because the IIFE will be anonymous, it doesn't end up as a global variable, and neither will the properties I don't want. Neat!

Here's how it works:

First, create your immediately invoked function, and pass the object as a parameter to it.

(function() { 
  
})(originalObject);

Now, let's return the object from the function.

(function(object) { 
  return object;
})(originalObject);

Ok, so far, we've got a function that runs, takes an object as a parameter, and returns the same object. That's... not what you want. But here comes the ✨magic✨. We're going to destructure the object that's passed to the function. Our destructuring pattern will be { b, d, ...object }.

let newObject = (function({ b, d, ...object }) { 
  return object; 
})(originalObject);

By destructing the keys we don't want, we end up with only the remaining properties in the ...rest property, which we name ...object. And our function returns that object, without the unwanted properties.

Ok, that's great, but can you do it in a one-liner?

I'm not a huge fan of cramming as much code as I can into a single line. I prefer to split things into multiple lines (where it makes sense), and then add plenty of comments. Because I'm not going to remember what the code does or how it works weeks or months from now.

But, if you do want a single liner, you can use an arrow function to shrink that code down, and it would look like this:

let newObject = (({ b, d, ...object }) => object)(originalObject);

I really like this pattern. I think it's much better than creating a copy of the full object and then deleting the properties you don't want. Why copy them over in the first place if you don't need them?

Hopefully, you'll find it useful too!