Spread Operators vs Rest Parameters in Javascript

Spread syntax (…) is a new feature in ES6. It’s super useful for programmers, as it is more readable and more functional.

Megan Lo
6 min readNov 17, 2020
Source: codeburst.io

Table of Content
Introduction
Spread Operator
Rest Parameter
Conclusion

I’m here to thank https://farmhouseguide.com/name-ideas-for-pet-turkey/ for turkey names.

Introduction

Alright, spread syntax(…). What are you? A lot of you may have already heard of it, since it is one of the most used features, and possibly one of the new ES6 features you would encounter the most. The three dots have two use:

  1. Spread Operator

Spread operator is useful when using something iterable, like an array expression or string to be expanded without mutating. If you still don’t understand, no worries, I’ll dive deep into the functionality of spread operator in a bit.

I personally like spread operator and have been using here and there. In this article, we would discuss the difference with the pre-ES6 methods.

2. Rest Parameter

I have to be honest, I haven’t had a chance to use rest parameter as a Javascript novice. But I found it super interesting and I’d like to include this in my article. Rest parameter is an improved way to handle function parameter. With the help of a rest parameter, a function can be called indefinite numbers of arguments. It doesn’t matter how it defines.

Source: Avengers: Infinity War

Oof *insert Jake Peralta’s voice* chills literal chills!! I am so excited to get into this learning journey with you guys!!

Spread Operator

  1. … vs concat()

// concat()

let someEastCoastStates = ["Connecticut", "New York", "Virginia"]
let someEastCoastStates2 = ["Massachusetts", "New Hampshire", "Pennsylvania"]
someEastCoastStates = someEastCoastStates.concat(someEastCoastStates2)console.log(someEastCoastStates)
// ["Connecticut", "New York", "Virginia", "Massachusetts", "New Hampshire", "Pennsylvania"]

// …

let someEastCoastStates = ["Connecticut", "New York", "Virginia"]
let someEastCoastStates2 = ["Massachusetts", "New Hampshire", "Pennsylvania"]
someEastCoastStates = [...someEastCoastStates, ...someEastCoastStates2]// someEastCoastStates is now ["Connecticut", "New York", "Virginia", "Massachusetts", "New Hampshire", "Pennsylvania"]

Saved a lot of trouble to type that concat()!

Or we can do reversely:

someEastCoastStates = [...someEastCoastStates2, ...someEastCoastStates]// someEastCoastStates is now ["Massachusetts", "New Hampshire", "Pennsylvania", "Connecticut", "New York", "Virginia"]

2. Copy Array

let someWestCoastStates = ["Washington", "Oregon", "California", "Arizona"]
let someWestCoastStates2 = someWestCoastStates
someWestCoastStates2
// ["Washington", "Oregon", "California", "Arizona"]

What if we want to add an element to our newly copied array?

someWestCoastStates2.push("Nevada")console.log(someWestCoastStates2) 
// ["Washington", "Oregon", "California", "Arizona", "Nevada"]
// yay it worked! But wait, hold on! Let's check our original array
console.log(someWestCoastStates)
// ["Washington", "Oregon", "California", "Arizona", "Nevada"]
// Um Esqueeze me???

This is not the situation we want, since we only want to change our newly copied array. This is why spread operator would come in handy.

let someWestCoastStates = ["Washington", "Oregon", "California", "Arizona"]let someWestCoastStates2 = [...someWestCoastStates]someWestCoastStates2.push("Nevada")// someWestCoastStates2 is now ["Washington", "Oregon", "California", "Arizona", "Nevada"]
// someWestCoastStates is not mutated at all.

Using spread operator would ensure that the original array would not be mutated.

3. Expand the Array

Normally, in order to expand the array, we would do:

let peanutCharacters = ["charlie brown", "snoopy", "sally brown"]
let morePeanutCharacters = [peanutCharacters, “peppermint patty”, “woodstock”]
console.log(morePeanutCharacters)
// [["charlie brown", "snoopy", "sally brown"], “peppermint patty”, “woodstock”]

So… it’s an array inside of an array, which creates a multidimensional array… Hm. Well, spread operator is a good option to help us solve the problem for us.

let peanutCharacters = ["charlie brown", "snoopy", "sally brown"]let morePeanutCharacters = [“peppermint patty”, ...peanutCharacters, “woodstock”] 
// you could even put the array into the desired position of your new array!
console.log(morePeanutCharacters)
// ["peppermint patty", "charlie brown", "snoopy", "sally brown", "woodstock"]
console.log(peanutCharacters)
// ["charlie brown", "snoopy", "sally brown"] yep, not mutated at all

Basically, you can see the three-dot is doing its magic for us without writing too much, or getting too complicated to read for other programmers.

Quick Note 1: Spread operators can also be used in Object literal {} which is a new feature in ES2018!

let peanutsComicFact = {
1: Woodstock was first seen in the strip in 1967 but was named in 1970 after the summer music festival,
2: Snoopy's brother Spike is from Needles, California
}
let peanutsComicFact2 = {
3: The Little Red Haired Girl was real,
4: Charles Schulz had to argue that the very first Peanuts animated special (A Charlie Brown Christmas) did not have a laugh track added to it. The producers didn't like it, but it became an instant hit
}
let mergedPeanutsComicFactObj = { ...peanutsComicFact, ...peanutsComicFact2 }
Object {
1: Woodstock was first seen in the strip in 1967 but was named in 1970 after the summer music festival,
2: Snoopy's brother Spike is from Needles, California,
3: The Little Red Haired Girl was real,
4: Charles Schulz had to argue that the very first Peanuts animated special (A Charlie Brown Christmas) did not have a laugh track added to it. The producers didn't like it, but it became an instant hit
}

You can also destructure it!

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }
console.log(x) // 1
console.log(y) // 2
console.log(z) // { a: 3, b: 4}

Quick Note 2: Make sure the object that spread operators are used on is iterable. Objects themselves are not iterable:

let obj = { 'key': 'value' }
let array = [...obj] // TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))

Rest Parameter

Sometimes when we are writing a function, we want to include as many arguments as we can, but what if we got lazy, just kidding (or am I? 🤪) or we don’t know how many arguments we need to take for a function. That’s when rest parameter becomes super handy in this case.

Without rest parameter:

function fun(a, b) {
return a + b
}
console.log(fun(1, 2)) // 3
console.log(fun(1, 2, 3, 4, 5, 6)) // 3, because the function will only take the first two arguments.

With rest parameter:

function fun(...args) { 
let sum = 0
for(let i of args) {
sum += i
}
return sum
}
console.log(fun(1, 2)) // 3
console.log(fun(1, 2, 3)) // 6
console.log(fun(1, 2, 3, 4, 5, 6)) // 21

Conclusion

I love the spread syntax. It has provided us a lot of functionalities and we can make great use out of it. Also, most importantly to all the beginners out there, like me (to this date), I personally think the spread syntax is very beginner-friendly. Instead of remembering the “complicated stuff,” like concat(), push(), etc, you might as well just use the spread operator. Jk, don’t take my words seriously! Sometimes these methods could be more useful to run big datas, but in practice, it’s always nice to work with the spread syntax to get a hand of it. I hope you enjoy my article! Who knows I might come with a more advanced version of this article in a year or so :)

Thanks for reading!

--

--

Megan Lo

Software Engineer @ Citi | I write about JavaScript.