It’s come up twice in the last couple of weeks, so I thought it might be a good time for a blog post!
Object.assign?
Ever passed around an Object and needed to modify a key? But you don’t want that modified object running around and causing other problems? There’s a cool useful web technology for that!
Object.assign allows you to copy values from one+ object(s) to another.
If you want to make a copy of an Object, you can do this with:
Object.assign({}, objectToCopy)
If you want to merge two objects into a new object, but without modifying them:
Object.assign({}, objectToCopy, anotherObjectToCopy)
If these objects share any keys, the last object wins!
Try running this in your console:
var obj = { a: 1, b: 2}
var newObj = Object.assign({}, obj, {b:3})
console.log(obj)
// obj remains the same because the first argument to Object.assign is {}
console.log(newObj)
// newObj has our overrides
var obj2 = { c: 1, d: 2}
var newObj2 = Object.assign(obj2, {b:3})
console.log(obj2)
// obj2 is modified
console.log(newObj2)
// newObj2 is the same as obj2 now
console.log(obj2 === newObj2)
Can I use it?
Of course you can! … if you have Babel/a build system 😉 IE 11 is the holdout among major browsers, so if you have to care about that, looks like you need a polyfill.
[EDIT] A good point was made in the comments (and I meant to address here!): if your object has nested properties, these will not copy as you might expect.
var obj = { a: 1, b: { c: 2, d: 3 } }
console.log(obj)
// {a: 1, b: { c: 2, d: 3 }}
var obj2 = Object.assign({}, obj, { b: { e: 4 } })
console.log(obj2)
// {a: 1, b: { e: 4 }}
// No c or d properties!
console.log(obj)
// {a: 1, b: { c: 2, d: 3 }}
// the original remains the same
There’s another example in the MDN docs about how you can accidentally override the original object as well, which is also concerning. So be careful with nested objects! There’s some npm modules that are happy to help if you need to deep copy/deep clone.
I also like:
const data = Object.assign({}, DEFAULTS, userData);
yes! nice pattern.
This is great but you should warn from deep clone:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Deep_Clone
Don’t forget that getters and setters get lost in the process and that Symbols, by default, are enumerable so these are also copied around.
`Object.assign` has a good use case mostly exclusively with setup/option objects, nothing else.