DEV Community

Cover image for You don't know spread operator !
Valentin PARSY
Valentin PARSY

Posted on

You don't know spread operator !

I was recently reading a blog post about iteration from Axel Rauschmayer (I suggest you follow him, all his posts are minegold for JS devs).
This post was mindblowing to me as I learned so much about iteratables in JavaScript.

Let's challenge our knowledge

Let me sum up a bit of what I learned here with a small challenge to you :
When I use the spread operator on a Number, I want the result to be an array that counts from 1 to the given value :
Example in the chrome console

First steps to an answer

First thing to do is try the code for yourself and you will see that using a spread operator on a Number throws an error => Uncaught TypeError: X is not iterable

Then what is an iterable ?
An iterable is an object that defines an iteration behavior, meaning it has a property with a Symbol.iterator key and an iterator as value.
This iterator should respect the iteration protocol which means it is a function that returns an object with a next fonction that returns an object with 2 properties : "value" (the current iteration's value) and "done" (a boolean indicating weither we are done iterating with this iterator or not).

The spread operator is simply a consummer of such iterables: when you give it an iterable, it'll call the next function of its Symbol.iterator property until it returns an object with {done: true} (and push each time the result in an array).

Verify that with an Array

An array in JavaScript is an iterable since it has an iterator as a value of its property with Symbol.iterator key.
Here is how you can use this iterator :
Usage of an array iterator in the chrome console

Answer to the challenge

So how do I make the spread operator not throwing an error when given a number ? You set the Symbol.iterator property on the Number primitive wrapper object.
Let's make all numbers iterables !
Setting the property on the Number's prototype

Conclusion

Obviously you never want to change the prototype of a primitive wrapper object, it's too dangerous.
But the knowledge of how iteration and the spread operator works is I think very valuable as a developper.

Top comments (5)

Collapse
 
sadanandpai profile image
Sadanand Pai •

Very simple if used generator

Number.prototype[Symbol.iterator] = function* () {
for (let i = 1; i <= this; i++) yield i;
};

Collapse
 
parsyvalentin profile image
Valentin PARSY •

Exactly, I wanted to keep this simple for people not knowing anything about this subject (like me 2 weeks ago =D )
But from there you can go absolutely nuts ! The sky is the limit ! You can actually declare the iteration protocol inside a class, then all your "instances" are iterables.

Collapse
 
ca0v profile image
Corey Alix •

Why is it dangerous?

Collapse
 
parsyvalentin profile image
Valentin PARSY •

The Number primitive wrapper object is used EVERYWHERE. If you change anything that "low-level" in your code, it will change it everywhere in your code/app, potentially changing the behavior of (in this example) every Number you use.

As a solution you could have your own IterableNumber, that is a Number to which you set the Symbol.iterator property. (not sure it is a good solution though)

Collapse
 
loclv profile image
Luu Vinh Loc •

I think there are a case to be made teammate (include me) confused.

a = 8
[...a]
// output 🚀: [1, 2, 3]

// now set it's value again
a = 's'
[...a]
// output 🚀: ['s']
Enter fullscreen mode Exit fullscreen mode