Defensive coding in Javascript
- email dev
- js
- javascript
- code reviews
- nullish coalescing operator
- optional chaining
- best practice
- defensive coding
- default value
Wed, December 1, 2021
Recent evolutions of Javascript have brought some real cool and useful features, actionable every day.
One that I keep using lately and I’ve been recommanding a few times in my code review is the combination “optional chaining ( ?. )” + “Nullish coalescing operator ( ?? )”:
For example I’ve seen in our codebase something like:
I’ve stumbled upon this today whith some deeply nested objects. A potential issue happening when we want to use the value of a property located deep within a chain of connected objects, like in our example. We do have to check (as we did in our example using a ternary operator), to avoid it to throw an error
Error: can't access property "unsavedChanges", component.emailLocalizationComponent is undefined`.
So let’s see 3 possibilities:
- ☠️ The one that could potentially throw an error like mentionned above if
emailLocalizationComponentdoes not exists as a property of thecomponentobject:
let unsavedEmailLocalization =
component.emailLocalizationComponent.unsavedChanges;
- 👍 Now what I saw in our codebase (it works, but it could be better):
let unsavedEmailLocalization = component.emailLocalizationComponent
? component.emailLocalizationComponent.unsavedChanges
: false;
- 🏆 But as I said in intro, modern JS offers great new features to combine checking for
nullorundefinedand assigning a default value, all in an easy 1 liner:
let unsavedEmailLocalization =
component?.emailLocalizationComponent?.unsavedChanges ?? false;
This way we have a concise way to both:
- Be on the safe side and future proof by avoiding the script to break when trying to assign the value of a property that might be missing
- Yet if this happens, assigning
undefinedis useless, so let’s be ahead of it and give it a default value with the nullish coalescing operator, which assign a value if the left side evaluates tonullorundefined - Note that a similar thing exist with the “Logical OR (||) operator”, the big difference is that the logical OR (||) does assign a default value as well, but it will check for truthy and nut nullish, which means that it would not assign values such as
falseor0or even an empty string''. But those values are often useful values. This is why my goto is the nullish operator??
What about support: if you don’t need to support IE then you’re fine. If you do … well …that’s a pity 😅