스프레드 문법은 ES6
에 도입되었네요. (정말 ES6
때 추가된 게 많죠?!)
스프레드 문법은 정말 몇 가지 중요한 특징만 알면 매우 유용하고, 그렇게 어렵지 않은 친구에요.
Object
)는 절대 이터러블이 아닙니다! 혼동 금지!)Symbol.iterator
을 통해 순회된 값들의 목록입니다.Rest
와 혼동하지 말아야 합니다. Rest
는 parameter
들을 하나의 배열로 만들기 위한 것이며, Spread
는 배열을 분해하여 일련의 값 목록으로 변환하는 작업입니다.우리, 레거시를 이해할 필요도 있으니 이를 탐구해보는 것도 적절한 것 같아요.
당시에는 Function.prototype.apply
를 통해서 배열을 인자로 전달했었습니다.
💡 아! 미리 말씀드리지만, 이러한 방식이 절대 나쁘다는 것이 아닙니다.
다만, 우리가 나중에 예전 코드를 봤을 때 "굳이..."라고 떠올릴 수 있기 때문에, 예전 코드들을 이해하자는 취지에서 서술합니다 😉
const values = [1,2,3,4,5]
console.log(Math.max.apply(null, arr)); // 5
// spread operator
console.log(Math.max(...arr)) // 5
또한, 이전에는 다음과 같이 배열을 전달해야만 했어요.
console.log([1,2,3].concat([4,5])) // [1,2,3,4,5]
// spread operator
console.log([1,2,3, ...[4,5]]) // [1,2,3,4,5]
배열 복사 역시 얇은 복사 차원에서 매우 간단합니다.
console.log([1,2,3,4,5].slice()) // [1,2,3,4,5]
// spread operator
console.log([...[1,2,3,4,5]) // [1,2,3,4,5]
이터러블의 경우에는 다음과 같이 배열로 변환했었는데요.
스프레드를 사용하니 매우 간편해졌군요!
function sum() {
const args = Array.prototype.slice.call(arguments);
return args.reduce(function (pre, cur) => pre + cur, 0)
}
// spread operator
function sum() {
return [...arguments].reduce(function (pre, cur) => pre + cur, 0)
}
// Rest parameter
function sum(...args) {
return args.reduce(function (pre, cur) => pre + cur, 0)
}
ES2021
부터 통과된 표준인데요!
객체 리터럴에서는 객체가 이터러블이 아니지만 예외적으로 사용할 수 있게 되었습니다!
이전에는 Object.assign
을 통해서 여러 객체를 병합하거나, 얇은 복사를 수행했어요.
하지만 스프레드 문법으로 이제 충분히 대체가 가능하다는 점, 참고해주세요!
const initialState = { a: 1, b: 2 }
const state = Object.assign(initialState, { c: 3 });
console.log(state)
// spread operator
const initialState = { a: 1, b: 2 }
const state = { ...initialState, { c: 3 }};
console.log(state)
생각보다 간단하죠? 그리고 매우 강력합니다.
실제로 리액트와 같은 라이브러리에서 불변성을 지킬 때 매우 자주 사용하게 되는데요.
핵심은 이터레이터의 결과로 생성된 일련의 값들의 목록을 반환한다는 점입니다.
그렇기에 새로운 배열로 받으면 얇은 복사가 되는 것이지, 그 값들이 참조하고 있는 메모리 주소값은 타입에 의존합니다.
절대 깊은 복사가 되지 않는다는 점 유념해주면서, 사용해주시면 될 것 같아요! 😉
그럼, 즐거운 코딩하시길 바라며. 이상! 🌈