puddlejumper26 / blogs

Personal Tech Blogs
4 stars 1 forks source link

Spread Operators and Rest Parameters #38

Open puddlejumper26 opened 4 years ago

puddlejumper26 commented 4 years ago

Translated from here [1]

In JS many build-in functions could be passed with multiple parameters.

e.g.

Rest Parameters

Notice 👇

Rest Parameters
Spread Operators

In JS, normally, no matter how many parameteres were passed, it will always work.

function sum(a, b) {
  return a + b;
}

alert( sum(1, 2, 3, 4, 5) );

Although the extra parameters will not work, only the first two parameters will be added.

Therefore, we could use Rest to define the funtion.

function sumAll(...args) { // 数组变量名为 args
  let sum = 0;

  for (let arg of args) sum += arg;

  return sum;
}

alert( sumAll(1) ); // 1
alert( sumAll(1, 2) ); // 3
alert( sumAll(1, 2, 3) ); // 6

:heavy_exclamation_mark: Notice ---> The rest parameters must be at the end

We could also define several parameters and use Rest for the rest of parameters

function showName(firstName, lastName, ...titles) {
  alert( firstName + ' ' + lastName ); // Julius Caesar

  // titles Array has the rest parameters
  // therefore the titles = ["Consul", "Imperator"]
  alert( titles[0] ); // Consul
  alert( titles[1] ); // Imperator
  alert( titles.length ); // 2
}

showName("Julius", "Caesar", "Consul", "Imperator");

'arguments' variable

:x: Arrow functions do not have "arguments"

function showName() {
  alert( arguments.length );
  alert( arguments[0] );
  alert( arguments[1] );

  // it's iterable
  // for(let arg of arguments) alert(arg);
}

// shows: 2, Julius, Caesar
showName("Julius", "Caesar");

// shows: 1, Ilya, undefined (no second argument)
showName("Ilya");

Spread Operator

To put an array into the list of parameters

e.g. there’s a built-in function Math.max that returns the greatest number from a list:

alert( Math.max(3, 5, 1) ); // 5

if we have [3,5,1], how should we pass this array into the Math.max?

let arr = [3, 5, 1];

alert( Math.max(arr) ); // NaN

This is not working, cause Math.max expects a list of numeric arguments, not a single array.

Spread operator to the rescue! It looks similar to rest parameters, also using ..., but does quite the opposite.

:point_right: When ...arr is used in the function call, it “expands” an iterable object arr into the list of arguments.

:small_orange_diamond: single array

let arr = [3, 5, 1];

alert( Math.max(...arr) ); // 5 (spread turns array into a list of arguments)

:small_orange_diamond: multiple arrays

let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];

alert( Math.max(...arr1, ...arr2) ); // 8

:small_orange_diamond: Spread operator and normal

let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];

alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25

:small_orange_diamond: Merge array

let arr = [3, 5, 1];
let arr2 = [8, 9, 15];

let merged = [0, ...arr, 2, ...arr2];

alert(merged); // 0,3,5,1,2,8,9,15 (0, then arr, then 2, then arr2)

:point_right: Not only the array, but also any iterable :point_down:

:small_orange_diamond: Turn String into Array

let str = "Hello";

console.log([...str]); // ["h", "e", "l", "l", "o"]
console.log(Array.from(str));   ["h", "e", "l", "l", "o"]

:heavy_exclamation_mark: difference between Array.from(obj) and [...obj]

Conclusions

:heavy_exclamation_mark: an easy way to distinguish between them:

Reference

[1] https://zh.javascript.info/rest-parameters-spread-operator