If you Wannabe (assigned) in my JS Object: Conditionally adding properties to JS Objects
Jonathan Silvestri
Posted on May 21, 2019
If you've worked with objects in JavaScript, you may have come across situations where you need to optionally add values to an existing object. To illustrate my example, I'd like to welcome the Spice Girls to this corner of the internet.
Traditionally, you could assign values like this:
function relationship(name, youGotWithMyFriends) {
var interestedParty = {
name: name
}
if(youGotWithMyFriends) {
interestedParty.lover = true
}
return interestedParty
}
// Later in our code...
var person = relationship('person', false)
console.log(person) // { name: 'person'}
var nextPerson = relationship('match', true)
console.log(nextPerson) // { name: 'match', lover: true }
As the Spice Girls clearly outlined for us in 'Wannabe', you'll need to get with their friends to be a lover.
Now, one could argue that you can add the lover
property to all the objects and have it be false by default. Totally valid, but for the purposes of this example, let's say that we don't want a lover
property unless it is true, and keep going down this path.
What if we had to add further properties with additional guard clauses that prevent assigning falsey values to our object? it might get a little unfun to have to write if
statements over and over.
Modernizing our approach, with ES6
With ES6, we gained access to the spread syntax. Useful for taking values from one collection and spreading them into another one, but our above example can also leverage this syntax!
Let's have another chat with the Spice Girls and see what they think about our fun new ES6 functionality...
function relationship(name, youGotWithMyFriends) {
return {
name,
...(youGotWithMyFriends && { lover: true }) // !!!
}
}
// Later in our code...
const person = relationship('person', false)
console.log(person) // { name: 'person'}
const nextPerson = relationship('match', true)
console.log(nextPerson) // { name: 'match', lover: true }
We get the same result! But umm...Spice Girls...
What's going on?
Let's go over our line that leverages the spread operator to add that property to the return object, ...(youGotWithMyFriends && { lover: true })
, and talk a bit about what's happening.
In the case of youGotWithMyFriends
being true
, you end up continuing in your code and hitting the { lover: true }
piece, and because the spread syntax is in use, it will spread the contents of that object to the object it is nested in, giving you the second console.log
value!
But what happens if that boolean is false
? Can you "spread" false on to an object without an error being thrown?
The spread syntax can be thought of as a shorthand, more straightforward Object.assign
function call. When you utilize it, it is like calling the function as follows:
Object.assign(targetObject, thingsToAddToTarget)
We can see how our first example works when we use Object.assign
, as thingsToAddToTarget
will just be our new object. But let's talk about the case of false being passed as the second argument:
const targetObject = {}
Object.assign(targetObject, false) // returns {}
Sometime during Object.assign
's implementation cycle, the team working on it decided that if the second argument is not an indexed value, instead of failing loudly, it will ignore what is passed in and return your original object, unmodified! Try passing a number, a null, or even undefined in your browser console as a second argument to see for yourself :).
I hope you enjoyed this little example of leveraging a cool ES6 feature, and that you can find use-cases in your code today.
Posted on May 21, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
October 25, 2024