Trimming JavaScript: ditch verbosity, gain readability
Tags: javascript, readability, tips, beginners
Published: 2024-04-21 14:32:12

Are you familiar with expressions like these:
* `a !== undefined && a !== null ? a : b`
* `if (a.x === undefined || a.x === null) { a.x = b }`
* `{ foo: foo, bar: bar }`
* `a ? a.b : undefined`
* `function getX(o) { return o.x }`

What do they all have in common? They are highly verbose, and all have a nice shorthand alternatives. Let's see how we can improve each one of these:

## Nullish coalescing operator `??`

This operator checks the value of the left hand-side operand - if it's null or undefined, it returns the right hand-side operand. Otherwise it returns the left hand-side, without evaluating the right hand-side.
This allows simplifying the following expression:
```javascript
a !== undefined && a !== null ? a : b
```
To this:
```javascript
a ?? b
```
Unlike `||` operator that checks for any falsy value, this operator only checks for nullish values - meaning `null` or `undefined`. Therefore it is safer to use in cases that `a` is a boolean which can be `false` or a number which can be `0`, and then `a || b` will return the value of `b`

## Nullish coalescing assignment `??=`

This operator only evaluates the right operand and assigns to the left if the left operand is null or undefined.
So we can simplify this expression:
```javascript
if (a.x === undefined || a.x === null) { 
  a.x = b 
}
```
to this:
```javascript
a.x ??= b
```

## JSON shorthand syntax

The shorthand syntax was introduced with ES6 and is already pretty common. 
Use it to shorten this:
```javascript
const name = 'john doe'
const age = 32
const talk = text => void console.log(text)
const person = {
  name: name,
  age: age,
  talk: talk
}
```
to that:
```javascript
const name = 'john doe'
const age = 32
const talk = text => void console.log(text)
const person = {
  name,
  age,
  talk
}
```

## Optional chaining `?.`

This operator accesses an object's property just like `.` does. However, unlike `.`, if the object is null or undefined, the expression will return `undefined` instead of throwing an error.
This allows replacing this code:
```javascript
a ? a.b : undefined
```
with that:
```javascript
a?.b
```

This operator is pretty strong, and can be used in various ways:
* Chaining: `a?.b?.c?.d`
* Call interface method: `someInterface.customMethod?.()`
  Note that in this case, if `customMethod` exists, but it is not a function, you'd still get an exception `someInterface.customMethod is not a function`
* Access dynamic property with bracket notation: `x?.[propname]`
* Access array items: `array?.[50]` - even if array is nullish, you'd get `undefined` instead of an exception

## Arrow functions

There's a lot to say about [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), but in the context of this post I want to focus on a specific use - 1 liner methods that calculate something or access some property. They have 2 attributes that help with code shortening:
* Arrow functions that do not have a block body wrapped with curly brackets `{/*...*/}` have an implicit `return`. 
* in a single-param arrow function you do not have to put the argument in parentheses 
Meaning, you can change this:
```javascript
function getX(o) { 
  return o.x 
}
```
with this
```javascript
const getX = o => o.x
```

This is super useful, for example, for mapping functions.
Note that there are some caveats though:
* Arrow functions do not have `this`
* Arrow functions do not have `arguments`. You can use spread operator instead. E.g `(...args) => args[0]` 
* Arrow functions cannot call `super` or be used as constructors