Quirky Spread Operator in Javascript

Sometimes you error, and sometimes you don’t, Why? Javascript, Why?

Mr Super Shetty
A Web Developer
4 min readNov 14, 2022

--

If you ask any javascript developer to tell the difference between rest and spread it will take them at least a few seconds to think. They are not to be blamed as both use the same three dots

Here is a quick explanation of what is what.

Rest:

Think of this like the Rest of Things. I want Apple, Banana or any other Fruits, that would be written as Apple, Banana, …Fruits. Although used in case of a function it can be used anywhere.

// in a function definition 
function person(name, age, …qualities)
// in a variable declaration
const {name, age, …qualities} = personObj

Spread:

Spread on the other hand is to open things into its individual parts. like individual items of an array or object. It’s great for creating a copy of an array or object

//object spread 
const newPerson = {…oldPerson}
//array spared
const newArray = [10,…oldArray];
//function spread
myFunc(...args);

Now some of you may have a valid question what all can you spread?
Answer: It depends

You can technically only spread “object object” or array because there isn't anything to spread in case of a normal variable. All the below will throw an error as you cant spread any variable.

//SyntaxError: Unexpected token '…' 
const v1 = …null;
const v2 = …10;
const v3 = …undefined;

What if we do it inside an array? Uh?? Not the same error.

//TypeError: Spread syntax requires …iterable not be null or undefined 
const a1 = […null];
const a2 = […10];
const a3 = […undefined];

Can you guess what error we get in case of a doing it inside an Object?
Nothing, it doesn’t throw any error, but the object is empty.

const o1 = {…null}; 
const o2 = {…10};
const o3 = {…undefined};

The short answer to why this difference: it’s one of the javascript’s gotcha. I know the language designers may have valid reasons but for us mere mortals it’s just a hindrance. These are like the beautifully designed doors that Don Norman talks about in his book The Design of Everything. To the language designers these doors work as they should but we are trapped as we don't know how they work and more importantly why.

The Simplest thing that the authors should have done is to give these two different names. Object Spread and Array Spread. Even the trusted MDN doesn't call out the difference or why?

Small detour. Having tripped over the error while spreading due to object being undefined, I had made it a practice to use an OR when spreading like below. During one of the PR reviews, I suggested the dev add an OR. He shared dev tools screenshots that showed it wasn’t necessary. That’s how i discovered this.

[...(a1 || [])]
{...(a1 || {})}

Back to Spreads. These have two different internal workings and hence are different. Let’s look at these two spreads

Object Spread

Object spread is equivalent to Object.assign() (mdn). In the official spec it’s mentioned if you try assigning null/undefined to an object it will make keys as empty list. Hence spreading inside an object doesn't fail if you try to spread a null/object inside an object.

The assign function is used to copy the values of all of the enumerable own properties from one or more source objects to a target object. When the assign function is called, the following steps are taken:

1. Let to be ToObject(target).
2. ReturnIfAbrupt(to).
3. If only one argument was passed, return to.
4. Let sources be the List of argument values starting with the second argument.
5. For each element nextSource of sources, in ascending index order,
…5.1. If nextSource is undefined or null, let keys be an empty List.

Array Spread

Array spread requires the thing that’s spread to be an iterator. Since null/undefined isn’t an iterator it throws a TypeError.

1. Let spreadRef be the result of evaluating AssignmentExpression.
2. Let spreadObj be GetValue(spreadRef).
3. Let iterator be GetIterator(spreadObj).
4. ReturnIfAbrupt(iterator).

This is why there is a difference between the two. Object spread doesn’t care if the variable is undefined and will handle it silently but array spread will throw an error. I will continue doing the OR syntax for both as it’s one less thing for my brain to remember. But you needn't follow my path.

Want us to write more

Hit claps if you liked it. It will encourage us to write more. Follow, for more posts. Comment below if you have any other suggestions or inputs. And now you know one more of these Javascript-y inconsistencies.

--

--