There is no such thing as the Spread Operator in JavaScript!
Tags: javascript
Published: 2020-04-10 15:09:30

---
title: There is no such thing as the Spread Operator in JavaScript!
published: true
description: There exist a common misconception in the Web regarding the Spread Syntax, which is presented as an operator.
canonical_url: https://medium.com/p/9c4e4dbd8a02
tags: javascript,
cover_image: https://cdn-images-1.medium.com/max/1000/1*c-pbsgWyWqKlJrzGNwweUQ.jpeg
---

Have you heard about the Spread Syntax? Introduced in ES2015, we love it due to its simple semantics and ubiquitous use cases. What about the [Spread Operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Spread_operator)? Yes, [it's the three dots](https://guide.freecodecamp.org/javascript/es6/spread-operator/) (`...`) used by the Spread Syntax!

…and by saying such things, we start digging into the horrifying world of [a bug's life](https://www.youtube.com/watch?v=cXWRAb84TTE)…

## A quick review of the Spread Syntax

A simple use case where we can leverage the use of the Spread Syntax is when we want to concatenate multiple arrays. Check the following snippet:

```js
const clientErrors = ['err1', 'err2', 'err3'];
const serverErrors = ['err4', 'err5'];

function numberOfErrors(clientErrors, serverErrors) {
  // Assuming that both inputs are arrays to prevent TypeErrors.
  return [...clientErrors, ...serverErrors].length;
}
numberOfErrors(clientErrors, serverErrors); // => 5
```

The function `numberOfErrors` concatenates two arrays and returns the length of the new array. But what if the parameters are falsy values, like `null` or `undefined`?

```js
const clientErrors = ['err1', 'err2', 'err3'];
const serverErrors = null;
function numberOfErrors(clientErrors, serverErrors) {
  return [...clientErrors, ...serverErrors].length;
}
numberOfErrors(clientErrors, serverErrors);
// => TypeError
```

We know that if we try to spread a `null` or `undefined` variable, this will make the interpreter nag. In real world scenarios, we want to guard ourselves from such edge cases. With a minor tweak, we end up writing something like this:

```js
const clientErrors = ['err1', 'err2', 'err3'];
const serverErrors = null
function numberOfErrors(clientErrors, serverErrors) {
  return [...(clientErrors || []), ...(serverErrors || [])].length;
}
numberOfErrors(clientErrors, serverErrors) // => 3
```

Because `serverErrors` is falsy, the logical OR operator will return an empty array, which then will be spread gracefully. The final result from calling `numberOfErrors` is equal to the length of the `clientErrors` array, which is `3`.

## Spread Operator Precedence

Now that we covered a basic example, let's see something more interesting. For each of the following questions, mark the correct answer. The solutions will be presented immediately after. *(**Hint**: You can run the code snippets and see the results yourself!)*

### Question A

```js
const a1 = null;
const b1 = [1, 2];
const c1 = [...a1 || b1];
```

What is the value of `c1`?

1. `c1` has no value. The expression `...a1` will throw `TypeError`, because `a1` is `null`.
2. `c1` is `[1, 2]`. The expression `a1 || b1` will be evaluated first, which then will return `[1, 2]`, which will be spread.

### Question B

```js
const a2 = [1, 2];
const b2 = null;
const c2 = [...a2 || b2];
```

1. `c2` is `[1, 2]`. The expression `a2 || b2` will be evaluated first, which will be spread.
2. `c2` is `[1, 2]`. The expression `…a2` will be evaluated first, which will be spread.

## Question C

```js
const a3 = null;
const b3 = null;
const c3 = [...a || b];
```

1. `c3` has no value. The expression `...a3` will throw `TypeError`, because `a3` is `null`.
2. `c3` has no value. The expression `a3 || b3` will evaluate first which will return `null` and then the Spread Syntax will throw `TypeError`.

### Answers

```
A. 2
B. 1 
C. 2
```

If it happens that you have not answered correctly to at least one of the above questions, then you might have fallen into the trap of the operator precedence. Does the dots punctuator `…` have higher precedence over the logical OR `||`, or is the other way around? What is the precedence of the Spread Operator? The correct answers is: **It does not matter, because there is no such thing as Spread Operator in JavaScript!**

## The Spread Operator does not exist!

When we try to evaluate expressions like `[…array || []]` it's logical to examine the precedence of our operators. There exist a common misconception in the Web regarding the Spread Syntax, which is presented as an operator.

A [great answer](https://stackoverflow.com/questions/44934828/is-it-spread-syntax-or-the-spread-operator/44934830#44934830) was posted in Stack Overflow by [Andrew Li](https://stackoverflow.com/users/5647260/andrew-li), which is worth mentioning and summarizes the nature of the Spread Syntax.

One of the most memorable arguments can be retrieved directly by the ECMAScript 2015 specification itself:

> The complete list of operators is listed in Clauses §12.5 through §12.15 in the  [ECMAScript 2015 Language Specification](http://www.ecma-international.org/ecma-262/6.0/), the specification in which `…` is introduced, which doesn't mention `...`. - [Andrew Li answer](https://stackoverflow.com/questions/44934828/is-it-spread-syntax-or-the-spread-operator/44934830#44934830)

Another worth-mentioning point is that *"An operator is a builtin function [..] that **evaluates to exactly one value**."*. If we try to run a statement like `const a = …b` in our Web Console, where `b` is an array, then we'll `SyntaxError`.

The way that the Spread Syntax works, is by evaluating its arguments first, and then spreading the result. Thus, `[…a || b]` behaves exactly the same way as `[…(a || b)]`. Putting a set of parentheses around `a || b` expression helps to remove the ambiguity.

> As a practical reference, Spread Syntax's arguments are evaluated first and then spread.