# Nullish coalescing and optional chaining in JavaScript


## Nullish coalescing operator

The nullish coalescing operator (`??`) is a logical operator that returns the right-side operand when the operand on its left-side either evaluates to `null` or undefined.

Unlike to logical OR operator (`||`) which returns the right-hand operand if the left is a falsy value, the nullish coalescing operator does not return the right-hand operand for other falsy values like `0` and `''`.

```javascript
const logical_or_test = 0 || 45;
const nullish_coalescing_test = 0 ?? 45;

console.log(logical_or_test); // 45
console.log(nullish_coalescing_test); // 0
```

According to the [tc39 proposal site](https://tc39.es/proposal-nullish-coalescing/#top), the design decisions made for the operator are:

> 1. The right argument of **`??`** is evaluated only if needed ("short circuiting").
> 2. **`??`** has lower precedence than **`||`**.
> 3. **`??`** cannot immediately contain, or be contained within, an **`&&`** or **`||`** operation.
> 4. The right argument is selected if the left argument is **`null`** or **`undefined`**.

### No chaining with AND or OR

Chaining the nullish coalescing operator with logical AND or OR will throw a syntax error. However, wrapping the expression with a logical AND or OR in a pair of parentheses to show precedence is fine.

**This throws a syntax error**

```javascript
0 || undefined ?? "a string";
```

**But this is okay, because of the parentheses**

```javascript
(0 || undefined) ?? 'a string';
```

To know more about nullish coalescing, [check out the documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_Coalescing_Operator).

## Optional chaining operator

The optional chaining operator (`?.`) is used to access nested properties of an object without having to check each reference for validity

It functions just as the chaining operator (`.`) except that it doesn't throw an error when a reference happens to be nullish (`null` or `undefined`). The expression is short-circuited with a return value of `undefined` when the property being accessed is nullish.

### Basic usage

Assuming we have an object containing some random properties

```javascript
const user = {
  name: {
    firstName: 'James',
    lastName: 'carter'
  },
  age: 24
};
```

To access the value of a nested property without having to validate.

```javascript
var hairColor = user.hair?.color;
console.log(hairColor); // undefined
```

This syntax simplifies the process of accessing properties which may potentially be nullish.

Trying to access the nested `color` property would throw an error:

```javascript
var hairColor = user.hair.color;
console.log(hairColor);
// => Uncaught TypeError: Cannot read property 'color' of undefined
```

Normally we would need to use the logical `AND` operator (`&&`) for validation:

```javascript
var hairColor = user.hair && user.hair.color;
console.log(hairColor); // undefined
```

We could also use the ternary operator for validation:

```javascript
var hairColor = user.hair ? user.hair.color : undefined;
console.log(hairColor); // undefined
```

### Optional chaining with function calls

Calling a function that doesn't exist using `?.` would return `undefined`. However, if the property name being invoked as a function exists already but not as a function, an error would be thrown.

```javascript
const user = {
  name: {
    firstName: 'James',
    lastName: 'carter'
  },
  age: 24
};

// accessing a non-existent method
console.log(user.name?.getInitials?.());
// => undefined
```

Firstly we check if the property name exists before invoking as a function, that way if the property is nullish, we get `undefined` instead of the error `undefined is not function`.

If a property name already exists but not as a function, we would get an error:

```javascript
console.log(user.name?.firstName?.());
// => Error: user.name.firstName is not a function
```

[Check out the docs on MDN to read more on optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining).

