ES6- Spread and Rest Parameters …

展開語法 Spread syntax/operator

1. Spread in function calls
1-1. replace slice.call() 把類陣列物件轉換成一個真正的陣列

ES5 : Array.prototype.slice.call(arguments,0)

function list() {
  return Array.prototype.slice.call(arguments);
}
console.log(list(1,2,3)); // [1, 2, 3] 
var obj = { 
 'length':4, 
 1:'123', 
 2:'223', 
 3:'333' 
} 
console.log(list(obj)); // [ <1 empty item>, '123', '223', '333' ]

ES6 : …

function listNew(...args){
  return args;
}
console.log(listNew(1,2,3)) // [ 1, 2, 3] same
console.log(listNew(obj)); // [ { 1: '123', 2: '223', 3: '333', length: 4 } ] unexpected

參考:淺談javascript的Array.prototype.slice.call

 

1-2. replace apply() 將數組傳入涵式參數

function myFunction(x, y, z) {
  console.log(x,y,z)
}
var args = [0, 1, 2];
//ES5
myFunction.apply(null, args); //1 2 3
//ES6
myFunction(...args); //1 2 3 same

2. Spread in array literals

concat:

var ary1 = [1, 2, 3]; 
var ary2 = [3, 4, 5];
var merge = [...ary1, ...ary2]; //[ 1, 2, 3, 3, 4, 5 ]

push:

var parts = ['shoulders', 'knees']; 
var lyrics = ['head', ...parts, 'and', 'toes']; 
// ["head", "shoulders", "knees", "and", "toes"]

slice: 淺拷貝

var arr = [1, 2, 3];
//ES5
var arr3 = arr.slice(); //[1, 2, 3]
arr3.push(5) //[1, 2, 3, 5]

//ES6
var arr2 = [...arr]; // [1, 2, 3]
arr2.push(4); // [1, 2, 3, 4]

3. Spread in object literals

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 }; //copy
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 }; //merge
// Object { foo: "baz", x: 42, y: 13 } 若相同key,後者蓋前者

剩餘參數 Rest parameters

1. 將不定長度的參數以陣列的形式傳入函示

function sum(...theArgs) {
  return theArgs.reduce((previous, current) => {
    return previous + current;
  });
}

console.log(sum(1, 2, 3));
// expected output: 6

console.log(sum(1, 2, 3, 4));
// expected output: 10

//多個參數也行
function test(a,...rest){
  console.log(a,rest); //1 [ 2, 3, 4, 5 ]
}
test(1,2,3,4,5); 

嗯嗯這邊的用法感覺跟argument很像,
官方文件也有寫到兩者的區別性:

剩余参数和 arguments对象的区别

剩余参数和 arguments对象之间的区别主要有三个:

  • 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参。
  • arguments对象不是一个真正的数组,而剩余参数是真正的 Array例,也就是说你能够在它上面直接使用所有的数组方法,比如 sortmapforEachpop
  • arguments对象还有一些附加的属性 (如callee属性)。

 

參考:

MDN – Spread_syntax 

MDN – Rest_parameters