written on 07/16/2019
Adding object properties conditionally with EcmaScript 6 (ES6)
📢 Question: What do you Frontend/Node developers use spread in object literals for (the ...o syntax inside object literals)? Ideally with concrete examples.
— Benedikt Meurer 🍀 @nodeconfeu 🇮🇪 (@bmeurer) June 7, 2019
Please help us on the @v8js team to understand your use cases so we can optimize the right things. 🙏
This was a tweet recently by an engineer from Google who is working on the V8 engine powering the Google Chrome web browser and Node.js. It got me to think what use-cases are extremely helpful for me and that I should share them with the world here.
Adding a property to an object
Adding a property to an object is quite easy in JavaScript. You can basically do it like in the following code.
1const person = {2firstName: "Max",3};4person.lastName = "";
But imagine the lastName should just be added if there is a specific conditional.
1const person = {2firstName: "Max",3};45const condition = getCondition();67if (condition) {8person.lastName = "";9}
This still looks fine but what if we combine conditions and add them into multiple if blocks?
1const person = {2firstName: "Max",3};45const condition = getCondition();6const additionalCondition = getAdditionalCondition();78if (condition) {9person.lastName = "";10}1112if (additionalCondition) {13person.addition = "";14}
It looks a lot harder to read overall and a function with this code would grow a lot even though it is just doing simple things.
EcmaScript 6 (ES6) is a new standard which enables a lot of new features in the language JavaScript. With those features, we could write the following code.
1const condition = getCondition();2const additionalCondition = getAdditionalCondition();34const person = {5firstName: "Max",6...(condition && { lastName: "" }),7...(additionalCondition && { addition: "" }),8};
The result of the value of person would be the same as in the script mentioned above. But how does this work?
The && operator
&&
is a logical operator in JavaScript and is combining boolean values by using AND . It can be used with two parameters. Let us assume those parameters are a and b . When we apply the &&
parameter it would look like a && b
. This will result in a boolean as a result which can be either true
or false
. It will be true if both of the parameters are also true . If one, or both, are false the result will be false too.
1const a = true;2const b = true;3const result = a && b;4console.log(result);5// Will log true
1const a = false;2const b = true;3const result = a && b;4console.log(result);5// Will log false67const c = false;8const d = false;9const result = c && d;10console.log(result);11// Will log false
A specialty is also that when not using booleans for a or b it can happen that no boolean is getting returned. We can simply check this by using the browser console.
1const a = true;2const b = "Magic String";3const result = a && b;4console.log(result);5// Will log "Magic String"
We can extend this feature and also return an object which is super nice.
1const condition = true;2const result = condition && { lastName: "" };3console.log(result);4// Will log { lastName: "" }
But somehow we need to merge this object into the person object above 🤯
Merging Objects
Merging objects is possible for a long time already in JavaScript with the Object.assign
functionality.
1const basePerson = {2firstName: "Max",3};4const person = Object.assign({}, basePerson, { lastName: "" });
What happens here is that the last parameter { lastName: ""}
gets merged into the object basePerson
. If properties would be the same the last object would win and overwrite the property of the preceding object. Also Object.assign is mutable function. This means it will apply all changes to the first parameter in all parameters of the function. To avoid changes to the basePerson object we pass an empty object as the first parameter, so a new object is being created rather than an old one which is reused.
EcmaScript 6 (ES6) offers a nicer way to do these merges.
1const basePerson = {2firstName: "Max",3};45const person = {6...basePerson,7lastName: "",8};
This would result in the same person object as before with the properties firstName
and lastName
. Also, here the last properties are overwriting the first properties, but we still have a problem of applying the object returned in the &&
expression into the object because the current version assumes that lastName
is just a key and has a static value.
We can pass an object to be destructured though into the person object to actually pass an object rather than key and a value.
1const basePerson = {2firstName: "Max",3};45const person = {6...basePerson,7...{ lastName: "" },8};
This might be enough now to refactor and put in a variable but we have one problem as const result = condition && { lastName: "" };
could result in either false
or { lastName: "" }
. If we pass the object ...{ lastName: "" }
to the destructuring function everything is fine but what is happening if we pass something like ...false in?
Actually, this would result in nothing when being used in an object. This also means we can use it in the big destructuring functionality.
1const basePerson = {2firstName: "Max",3};45const condition = getCondition();6const result = condition && { lastName: "" };7// Can be either false or { lastName: "" }89const person = {10...basePerson,11...result,12};13// Can be { firstName: "Max" } or { firstName: "Max", lastName: "" }
This is super nice but can be still improved by inlining the result somehow.
1const basePerson = {2firstName: "Max",3};45const condition = getCondition();67const person = {8...basePerson,9...(condition && { lastName: "" }),10};
This is a super slick example on how to extend objects conditionally in JavaScript and really shows that when using modern language we can use a more crisp syntax to express ourself.
These functions become especially important when you create the same type of object, sometimes with some properties and sometimes not. Think of factory functions for unit or integration tests.
If you are interested in more JavaScript content, check out my blog articles Add or delete a property of an object in JavaScript, How to debug JavaScript applications and tests or Function parameters in JavaScript.
You might also like
Add or delete a property of an object in JavaScript
Ever struggled with adding or deleting a property in JavaScript? Check this article out to learn how omitting or adding properties works in ES5 and in ES6.
Auto formatters for Python
🔥Save time by using the best auto formatters for python - a comparison to find the best for Python 2 and Python 3