객체의 rest와 spread 속성에 대해 설명하기 전에, 비슷한 기능을 먼저 살펴보자.
ECMAScript 2015에서는 배열 구조 분해 할당을 위한 rest 요소와 배열 리터럴을 위한 spread 요소를 도입했다.
// 배열 구조 분해 할당을 위한 rest 요소:
const primes = [2, 3, 5, 7, 11];
const [first, second, ...rest] = primes;
console.log(first); // 2
console.log(second); // 3
console.log(rest); // [5, 7, 11]
// 배열 리터럴을 위한 spread 요소:
const primesCopy = [first, second, ...rest];
console.log(primesCopy); // [2, 3, 5, 7, 11]
그렇다면 새로운 점은 무엇일까? tc39 Object Rest/Spread Properties for ECMAScript 제안에서 객체 리터럴에도 rest와 spread 속성을 사용할 수 있게 했다.
// 객체 구조 분해 할당을 위한 rest 속성:
const person = {
firstName: 'Sebastian',
lastName: 'Markbåge',
country: 'USA',
state: 'CA',
};
const { firstName, lastName, ...rest } = person;
console.log(firstName); // Sebastian
console.log(lastName); // Markbåge
console.log(rest); // { country: 'USA', state: 'CA' }
// 객체 리터럴을 위한 spread 속성:
const personCopy = { firstName, lastName, ...rest };
console.log(personCopy);
// { firstName: 'Sebastian', lastName: 'Markbåge', country: 'USA', state: 'CA' }
Spread 속성은 여러 상황에서 Object.assign()
보다 더 우아하고 좋은 방법을 제공한다:
// 객체의 얕은 복사:
const data = { x: 42, y: 27, label: 'Treasure' };
// 기존 방식:
const clone1 = Object.assign({}, data);
// 새로운 방식:
const clone2 = { ...data };
// 두 방식 모두 다음과 같은 결과를 얻는다:
// { x: 42, y: 27, label: 'Treasure' }
// 두 객체 병합:
const defaultSettings = { logWarnings: false, logErrors: false };
const userSettings = { logErrors: true };
// 기존 방식:
const settings1 = Object.assign({}, defaultSettings, userSettings);
// 새로운 방식:
const settings2 = { ...defaultSettings, ...userSettings };
// 두 방식 모두 다음과 같은 결과를 얻는다:
// { logWarnings: false, logErrors: true }
하지만 spread가 setter를 다루는 방식에는 미묘한 차이가 있다:
Object.assign()
은 setter를 트리거하지만, spread는 그렇지 않다.Object.assign()
이 자체 속성을 생성하는 것을 막을 수 있지만, spread 연산자는 그렇지 않다.Axel Rauschmayer의 글에서 이러한 주의점에 대해 더 자세히 설명하고 있다.
이 글은 v8.dev에 2017년 6월 6일 발행된 Object rest and spread properties 글을 한국어로 편역한 내용을 담고 있습니다.