Use JS object spread operator instead of Object.assign() pattern in Node 8

Adam Brodziak
2 min readDec 21, 2017

--

One of the best features of Node 8.6+ is the ability to use rest/spread operator for objects. It’s still an ESNEXT stage 3, but it’s so useful already. Take a look at the snippet:

const foo = { a:1, b:2, c: 3}
const bar = { d:4, b:9 }
const foobar1 = Object.assign({}, foo, bar)
const foobar2 = { ...foo, ...bar }
console.log(foobar1, foobar2)
console.log(JSON.stringify(foobar1) === JSON.stringify(foobar2))

Object.assign() issues

The biggest problem with Object.assign() is that it modifies the first argument. If you omit the empty object literal {} it will modify the first parameter and return reference to it:

const foo = { a:1, b:2, c: 3}
const bar = { d:4, b:9 }
const foobar3 = Object.assign(foo, bar)console.log(foobar3, foo)
console.log(foobar3 === foo) // true

Assign modified the first param and foobar3 is a reference to foo now.

I don’t know any solution, besides careful code review, to avoid this pitfall. Notice that using const foo did not prevented from modifying it. I haven’t found an ESLint rule that would prevent modification of first parameter in Object.assing() call.

But the object spread syntax is …ugh

Yeah, I’ve got the same feeling at the beginning, but quickly got used to it. For array rest/spread syntax is already part of ES2015 standard and becomes wildly used. That’s no a surprise, because in JavaScript there was no clean way to do head+tail list transformations prominent in Functional Programming.

As Corinne Kelly pointed out even the MDN docs uses “spread syntax operator” to describe Object.assign() behavior. It’s that common in FP and math notations:

Object.assign() syntax from MSN docs.

Note that there’s an ESLint rule that allows enforcing using object spread syntax instead of Object.assign() for object cloning, which prevents unintentional modification:

Object spread syntax benefits

  • Less cluttered code thanks to sparse syntax
  • Prevents accidental object modification
  • Can be enforced using ESlint rule
  • Douglas Crockford says so:

If I’m mistaken and there are better options let me know in comments or on Twitter.

--

--