파라미터 기본값, Rest 파라미터, Spread 연산자, Rest/Spread 프로퍼티

파라미터 기본값 (Default Parameter value)

ES6에서는 파라미터에 기본값을 설정하여 함수 내에서 수행하던 파라미터 체크 및 초기화를 간소화할 수 있다.

// ES5  
function  plus(x,  y)  {  
	x  =  x  ||  0;  // 매개변수 x에 인수를 할당하지 않은 경우, 기본값 0을 할당한다.  
	y  =  y  ||  0;  // 매개변수 y에 인수를 할당하지 않은 경우, 기본값 0을 할당한다.  
	return  x  +  y;  
}  
console.log(plus());  // 0  
console.log(plus(1,  2));  // 3
// ES6  
function  plus(x  =  0,  y  =  0)  {  
	// 파라미터 x, y에 인수를 할당하지 않은 경우, 기본값 0을 할당한다.  
	return  x  +  y;  
}  
console.log(plus());  // 0  
console.log(plus(1,  2));  // 3

Rest 파라미터

기본 문법

Rest 파라미터(Rest Parameter)는 Spread 연산자(`...`)를 사용하여 파라미터를 정의한 것을 의미한다. Rest 파라미터를 사용하면 인수의 리스트를 함수 내부에서 배열로 전달받을 수 있다.

function  foo(...rest)  {  
	console.log(Array.isArray(rest));  // true  
	console.log(rest);  // [ 1, 2, 3, 4, 5 ]  
}  
foo(1,  2,  3,  4,  5);

인수는 순차적으로 파라미터와 Rest 파라미터에 할당된다.

function  foo(param,  ...rest)  {  
	console.log(param);  // 1  
	console.log(rest);  // [ 2, 3, 4, 5 ]  
}  
foo(1,  2,  3,  4,  5);  
function  bar(param1,  param2,  ...rest)  {  
	console.log(param1);  // 1  
	console.log(param2);  // 2  
	console.log(rest);  // [ 3, 4, 5 ]  
}  
bar(1,  2,  3,  4,  5);

Rest 파라미터는 반드시 마지막 파라미터이어야 한다.

function  foo(  ...rest,  param1,  param2)  {  }  
foo(1,  2,  3,  4,  5);  
// SyntaxError: Rest parameter must be last formal parameter

arguments와 rest 파라미터

arguments 객체는 유사 배열 객체이므로 배열 메소드를 사용하려면 Function.prototype.call을 사용해야 하는 번거로움이 있다.

// ES5  
function  sum()  {  
	/*  가변 인자 함수는 arguments 객체를 통해 인수를 전달받는다.  
	유사 배열 객체인 arguments 객체를 배열로 변환한다.  */  
	var  array  =  Array.prototype.slice.call(arguments);  
	return  array.reduce(function  (pre,  cur)  {  
		return  pre  +  cur;  
	});  
}  
console.log(sum(1,  2,  3,  4,  5));  // 15
// ES6  
function  sum(...args)  {  
	console.log(arguments);  // Arguments(5) [1, 2, 3, 4, 5, callee: (...), Symbol(Symbol.iterator): ƒ]  
	console.log(Array.isArray(args));  // true  
	return  args.reduce((pre,  cur)  =>  pre  +  cur);  
}  
console.log(sum(1,  2,  3,  4,  5));  // 15

Spread 연산자

함수의 인수로 사용하는 경우

// ES5  
function  foo(x,  y,  z)  {  
	console.log(x);  // 1  
	console.log(y);  // 2  
	console.log(z);  // 3  
}  
// 배열을 분해하여 배열의 각 요소를 파라미터에 전달하려고 한다.  
const  arr  =  [1,  2,  3];  
// apply 함수의 2번째 인수(배열)는 분해되어 함수 foo의 파라이터에 전달된다.  
foo.apply(null,  arr);  
// foo.call(null, 1, 2, 3);

// ES6  
function  foo(x,  y,  z)  {  
	console.log(x);  // 1  
	console.log(y);  // 2  
	console.log(z);  // 3  
}  
// 배열을 foo 함수의 인자로 전달하려고 한다.  
const  arr  =  [1,  2,  3];  
/* ...[1, 2, 3]는 [1, 2, 3]을 개별 요소로 분리한다(→ 1, 2, 3)  
spread 연산자에 의해 분리된 배열의 요소는 개별적인 인자로서 각각의 매개변수에 전달된다. */  
foo(...arr);

배열에서 사용하는 경우

  1. concat

    // ES5  
    var  arr  =  [1,  2,  3];  	
    console.log(arr.concat([4,  5,  6]));  // [ 1, 2, 3, 4, 5, 6 ]
    
    // ES6  
    const  arr  =  [1,  2,  3];  
    // ...arr은 [1, 2, 3]을 개별 요소로 분리한다  
    console.log([...arr,  4,  5,  6]);  // [ 1, 2, 3, 4, 5, 6 ]
    
  2. push

    // ES5  
    var  arr1  =  [1,  2,  3];  
    var  arr2  =  [4,  5,  6];  
    // apply 메소드의 2번째 인자는 배열. 이것은 개별 인자로 push 메소드에 전달된다.  
    Array.prototype.push.apply(arr1,  arr2);  
    console.log(arr1);  // [ 1, 2, 3, 4, 5, 6 ]
    
    // ES6  
    const  arr1  =  [1,  2,  3];  
    const  arr2  =  [4,  5,  6];  
    // ...arr2는 [4, 5, 6]을 개별 요소로 분리한다  
    arr1.push(...arr2);  // == arr1.push(4, 5, 6);  
    console.log(arr1);  // [ 1, 2, 3, 4, 5, 6 ]
    
  3. splice

    // ES5  
    var  arr1  =  [1,  2,  3,  6];  
    var  arr2  =  [4,  5];  
    /*  apply 메소드의 2번째 인자는 배열. 이것은 개별 인자로 push 메소드에 전달된다.  
    [3, 0].concat(arr2) → [3, 0, 4, 5]  
    arr1.splice(3, 0, 4, 5) → arr1[3]부터 0개의 요소를 제거하고 그자리(arr1[3])에 새로운 요소(4, 5)를 추가한다.  */  
    Array.prototype.splice.apply(arr1,  [3,  0].concat(arr2));  
    console.log(arr1);  // [ 1, 2, 3, 4, 5, 6 ]
    
    // ES6  
    const  arr1  =  [1,  2,  3,  6];  
    const  arr2  =  [4,  5];  
    // ...arr2는 [4, 5]을 개별 요소로 분리한다  
    arr1.splice(3,  0,  ...arr2);  // == arr1.splice(3, 0, 4, 5);  
    console.log(arr1);  // [ 1, 2, 3, 4, 5, 6 ]
    
  4. copy

    ES5에서 기존 배열을 복사하기 위해서는 slice 메소드를 사용한다.
    Spread 연산자를 사용하면 보다 간편하게 배열을 복사할 수 있다.

    // ES5  
    var  arr  =  [1,  2,  3];  
    var  copy  =  arr.slice();  
    console.log(copy);  // [ 1, 2, 3 ]  
    // copy를 변경한다.  
    copy.push(4);  
    console.log(copy);  // [ 1, 2, 3, 4 ]  
    // arr은 변경되지 않는다.  
    console.log(arr);  // [ 1, 2, 3 ]
    
    // ES6  
    const  arr  =  [1,  2,  3];  
    // ...arr은 [1, 2, 3]을 개별 요소로 분리한다  
    const  copy  =  [...arr];  
    console.log(copy);  // [ 1, 2, 3 ]  
    // copy를 변경한다.  
    copy.push(4);  
    console.log(copy);  // [ 1, 2, 3, 4 ]  
    // arr은 변경되지 않는다.  
    console.log(arr);  // [ 1, 2, 3 ]
    

    Spread 연산자를 사용하면 유사 배열 객체(Array-like Object)를 배열로 손쉽게 변환할 수 있다.

    const  htmlCollection  =  document.getElementsByTagName('li');  
    // 유사 배열인 HTMLCollection을 배열로 변환한다.  
    const  newArray  =  [...htmlCollection];  // Spread 연산자  
    // ES6의 Array.from 메소드를 사용할 수도 있다.  
    // const newArray = Array.from(htmlCollection);
    

Rest/Spread 프로퍼티

// 객체 리터럴 Rest/Spread 프로퍼티  
// Spread 프로퍼티  
const  n  =  {  x:  1,  y:  2,  ...{  a:  3,  b:  4  }  };  
console.log(n);  // { x: 1, y: 2, a: 3, b: 4 }  
// Rest 프로퍼티  
const  {  x,  y,  ...z  }  =  n;  
console.log(x,  y,  z);  // 1 2 { a: 3, b: 4 }

// 객체의 병합  
const  merged  =  {  ...{  x:  1,  y:  2  },  ...{  y:  10,  z:  3  }  };  
console.log(merged);  // { x: 1, y: 10, z: 3 }  
// 특정 프로퍼티 변경  
const  changed  =  {  ...{  x:  1,  y:  2  },  y:  100  };  
// changed = { ...{ x: 1, y: 2 }, ...{ y: 100 } }  
console.log(changed);  // { x: 1, y: 100 }  
// 프로퍼티 추가  
const  added  =  {  ...{  x:  1,  y:  2  },  z:  0  };  
// added = { ...{ x: 1, y: 2 }, ...{ z: 0 } }  
console.log(added);  // { x: 1, y: 2, z: 0 }