The spread operator is a favorite of JavaScript developers. It's a powerful piece of syntax that has numerous applications.
So many, in fact, that...
For further actions, you may consider blocking this person and/or reporting abuse
Great examples!
Note that for merging objects, the keys in the later objects take precedence. e.g.
This is usually how I do optional options in an object.
If I have a function that accepts an object of options I'll spread them into the default options. It works great because all of the latter keys take precedence like you stated.
This totally works, but have you tried using default values in the function signature? I believe that was added in ES6, but I can't remember for sure.
I have and it works well for simple function signatures. But, when you reach a point where you have 5, 6, 7 optional parameters and you need to change the last one this pattern becomes a real pain. The problem is there is no way to invoke named function parameters, you have to do it by order.
If you add curlies, you can still specify the arguments in the signature but treat it as an object. Best of both worlds.
i do the same ;P
Absolutely important to point out! Thanks for mentioning it.
I like to use the Set Object with Spread Operator to display non-repeat data into Array:
Spread is a awesome feature.
Congratulations for the post!
Note that this only works if you have an array of primitive types
Was going to leave the same comment :)
Nice one!
Nice quick round up! Thanks! A quick word of warning, when copying an array, it does a shallow copy, so doing:
This will change
myarr
as well.Definitely. My understanding is that this only applies because the example above is multidimensional. So the first level is copied, but the deeper levels are referenced. If it's one-dimensional it is a deep copy.
Hey Laurie!
Good post, but just letting you know that your error example does work and will not throw an error.
Arrays are objects, where the index is the key. What you end up with in this example is:
Oops! I think I meant to flip that around. Will fix, thanks for catching it.
No problem!
Great stuff. Note that spread operator works also in deconstruction too, not only construction:
Take first (or n first) fields of an array:
Or as function definition:
Good one😍
Likewise for objects, can be used to create a new one that omits certain properties.
All great examples!
I always forget this since there seem to be more places to use the construction functionality. Thanks for the reminder!
Hi Lauri, thank you for this post, I'm just learning JS and this really helped me to understand the spread operator.
As I'm a beginner in JS I have a question: in the "Pass arguments as arrays" part, I understand that x=0, y=1, and z=2. What would happen if my function is expecting 3 parameters but for some reason, the array has 2 or 4 elements? Or we would simply try to make sure that the size of the array and the parameters expected by the function are equal?
The name of a function and the number of parameters it takes (the placeholders for arguments) represent something called a function signature. This is unique within the current scope of the program. If you were to pass too many arguments it would throw an error because it would not find a corresponding function signature, i.e. a function with that name taking 2 (or 4) elements.
That may be the case in other languages, but not in JS. In JS, if you pass too many arguments, the extras will be ignored (but accessible through the variable named
arguments
). If you pass too few arguments, the missing arguments will be given the valueundefined
(which may result in an error, but not definitely).You're correct, I put my Java hat back on and shouldn't have!
Looks like this has some good explanations. stackoverflow.com/questions/126940...
Got it, thank you!
You can also use it to conditionally add properties to objects.
I am using it in the React environment quite often and I'm curious if you have a clue about how the performance is compared to the equal methods like copying an array with spreading vs copying it via slice()?
It depends on the JS engine running, i.e. chrome vs safari. My understanding is that slice used to be more performant but that gap has been cut significantly and on many browsers, the spread operator is the same, or possibly better performance wise.
And since slice() only works for arrays, the spread operator is a more powerful piece of syntax.
Thanks for the answer, wasn't aware of it but a quick research confirmed it :)
Also, here's a nice quick way to go from Map to array of entries.
Great summary! Two extra thoughts:
Object.entries
, and in fact that Objects were iterable as entries the way that Maps are. I wish I could do stuff like this (but to be clear, this does NOT currently work):Sigh... but I dream...
Thank you for this article!
One note--I noticed a small typo in the Merge Objects example.
The second object should be named
obj2
Thanks! I’ll fix that when I have a moment.
Missing my favourite use, which is to conditionally and declaratively add keys to objects, which isn't possible otherwise.
Same for arrays
What is the way you always use to prevent error when data is null or undefined?
For my case, I always face this when 'initVar' is null or undefined. Or at lease 'aaa' is null or undefined.
const {aaa: {bbb, ccc}} = initVar
Maybe you could actually use the spread to start with default values and override with
initVar
:But not sure if that is really useful in maybe more complex deconstructions? :D
So that example is desrructhring assignment. I look at that in a different post which is linked at the bottom of this one.
Why would you copy an array like this, rather than
let copy = arr
?Because of it being a shallow copy.
The spread operator would mean this
However, this only works for flattened arrays. Multidimensional arrays will be deep copies at only the top level.
It does a deep copy for an array only, but does a shallow copy when used on an object. Is that right? Doesn't mention it in your article
That is correct. And yes, it's something that I likely should have mentioned!
Thank you for explaining! :)
I would love some real-world use cases for Rest as well. I rarely use it but I feel like thats because I lack enough understanding. Same goes with Switch though, I need to just use them more lol
I find rest parameters super useful for writing wrapper functions. For a super simple example, I often like to define small logger functions as wrappers around
console.log()
that always add certain context, such as a label that tells me where the log was issued:This is a pretty trivial example, but I've used it for much more complicated cases where I basically always use the same default arguments for calls to library functions with lots of arguments, and I want a wrapper that supplies all but the last couple arguments for me. I'll write a wrapper that gathers arguments into a rest array, then spreads them into the end of my call to the library function, like I did with
console.log
aboveThis is super awesome. I can see the value already! Thank you so much! 😁
Noted! Maybe I'll get to those in the future.
Awesome! Thank you for listening to my suggestion!
Interesting, thank you, I now understand the usage of spread operator.
So glad it helped!
Holy wow this just saved me so much time debugging an error ❤
I’m so glad!
This post is the must-read for understanding spread operations, great and concise article.
Thanks so much!
Great article!
Thanks so much Emma!
Great post Laurie! Spread operator is a fantastic tool and it keeps variables immutable which is a huge bonus.
Thanks!
My fav is the merge tip! Don't use that one very often, as well it's nice to refresh me on the different uses. Thanks Laurie!
Glad you liked it!
Thank you!