티스토리 뷰

Rest&Spread

Javascript Rest Parameter 와 Spread Syntax 활용

Rest 파라미터란

Rest 파라미터 구문은 정해지지 않은수 인수를 배열로 나타낼 수 있게합니다.

기본 자바스크립에서 ES5에서는 대부분 정해지지 않은 인수를 arguments collection을 사용하여 배열로 변환하여 다루었습니다.


function f(a, b) {
  //인수를 배열로 변경 -> bolierplate 발생
  var arr = Array.prototype.slice.call(arguments);
  
  //collection으로 사용할 수 없는 배열 기능들을 사용가능.
  var first = arr.shift(); 
}

ES6에서 위와 같은 상용구(bolierplate)를 줄이기 위해 Rest 파라미터가 도입되었습니다.

function f(...args) {
  
  //bolierplate 제거
  var arr = args;
  
  var first = arr.shitf();
}

Spread 연산자란

Spread 구문을 사용하면 배열이나 문자열과 같이 반복 가능한 문자를 0개 이상의 인수 (함수로 호출할 경우) 또는 요소 (배열 리터럴의 경우)로 확장하여, 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있습니다.

문법

함수 호출에서:

// 사용예 -  myFunction(...iterableObj);


function myFunction(x, y, z) {}
var args = [0 ,1, 2];

//ES5 에서 배열을 인수를 넘기는 방법
myFunction.apply(null, args);

//더 나은 방법으로 변경가능
myFunction(...args); // ...args => myFunction(0, 1, 2);

//인수목록을 확장 가능하게 함
var args = [0,1];
myFunction(...args,...[2]) // // ...args, ...[2] => myFunction(0, 1, 2);

배열 리터럴, 문자열에서:

// 사용예 - [...iterableObj, '4', 'five', 6];

// 배열을 일부로 하는 새로운 배열을 생성하기에 사용되는
// 'push', 'splice', 'concat' 등을 대체로 간결한 코드를 작성 할 수 있습니다.
var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and'] // ['head', 'shoulders', 'knees', 'and']

//배열 복사
var arr = [1, 2, 3];
var arr2 = [...arr]; 

//concat 대체
var arr1 = [1, 2, ,3];
var arr2 = [4, 5, 6];
arr1 = [...arr1, ...arr2];

객체 리터럴(ECMASCript2018 기능)

// 사용예 - let objClone = { ...obj };
var obj1 = { foo : 'bar', x : 42 };
var obj2 = { foo : 'baz', y: 13 };

//객체 복사
var clonedObj = { ...obj1 }; 

//객체 병합
var mergedObj = { ...obj1, ...obj2 }; 
// Object { foo : 'baz', x: 42, y: 13 }

Resting 과 Spreading을 쓸만한 예제

1. 프로퍼티 더하기

//객체 복사와 동시에 name 추가
const obj1 = { id: 'foo' };
const obj2 = { ...id, name : 'MyName' };

2. 객체 프로퍼티 제외하기

//구조분해 할당을 이용하여 name 제거 
const noName = ({ name, ...rest }) => rest 
const user = {
  id: 100,
  name: 'MyName',
  password: 'pwd'
}

noName(user) // Object { id: 100, password: 'pwd' }

//동적으로 프로퍼티 제외
const user = {
  id: 100,
  name: 'MyName',
  passworld: 'pwd',
}
//팩토리 함수를 이용하여 동적으로 제외하는 함수 생성
const removeProperty = prop => ({ [prop]: _, ...rest }) => rest;

const removePassword = removeProperty('password');

removePassword(user) // { id: 100, name: 'MyName' }

구조분해할당 - https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

3. 프로퍼티 기본값

const user = {
  id: 100,
  name: 'MyName',
};

const user2 = {
  id: 200,
  name: 'MyName2',
  addProp: ['Added Property']
}

//구조 분해 할당에 기본값을 추가하고 리턴되는 함수에 병합을 이용한 방법
const setDefaults = ({ addProp = [], ...obj }) =>
  ({ ...obj, addProp })
  
setDefaults(user); // { id: 100, name: 'MyName', addProp: [] }
setDefaults(user2); // { id:200, name: 'MyName2, addProp: ['Added Property'] }

4. 프로퍼티 이름변경

const renamed = ({ ID, ...obj }) => ({ id: ID, ...obj });

const user = {
  ID: 123,
  name: 'MyName'
};
renamed(user); // { id: 123, name: 'MyName' }

5. 조건적 프로퍼티 추가

const user = { id: 123, name: 'MyName' };
const password = 'pwd';
const userWithPassword = {
  ...user,
  id: 100,
  ...(password && { password }) //조건 password가 존재한다면 객체 리터럴을 이용하여 객체 생성후 객체 추가
}

userWithPassword // { d: 100, name: 'MyName', password: 'pwd' }

ES6를 활용한 문법으로 과거 복잡하고 boilerplate가 발생했던 코드들이 더 간결해졌습니다. MDN 의 Javascript Weekly에서 좋은 글을 발견하여 이렇게 정리합니다.
이 글에서 설명자체가 부족하지만 짧게 중요한 것들만 정리하였습니다.
자세한 설명은 참고부분을 이용하시기 바랍니다.

참고

'JavaScript' 카테고리의 다른 글

자바스크립트의 First-Class Function(일급함수) 정리  (0) 2019.03.13
Promise 정리  (0) 2017.09.28
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함