[JS] 스프레드 문법
스프레드 문법
일명 전개문법이라 불리는 스프레드 문법(Spread syntax)은 하나로 뭉쳐있는 여러 값들의 집합을 펼쳐서 개별적인 값들의 목록으로 만든다. ...
을 대상 앞에 붙여 사용하며, 사용 가능한 대상은 Array, String, Map, Set, DOM 컬렉션(NodeList, HTMLCollection), arguments와 같이 for … of문으로 순회할 수 있는 이터러블에 한정된다.
스프레드 문법의 결과는 값이 아니다. 즉 스프레드 문법 …이 피연산자를 연산해 값을 생성하는 연산자가 아니라는 말이다. 따라서 스프레드 문법의 결과는 변수에 할당할 수 없다.
const list = ...[1,2,3]; // SyntaxError: unexpected token ...
함수 호출문의 인수 목록에서 사용하는 경우
요소들의 집합체인 배열을 펼쳐서 개별적인 값들의 목록으로 만든 후 이를 함수의 인수 목록을 전달해야 하는 경우가 있다.
const arr = [1,2,3]
const max = Math.max(arr); // NaN
// Math.max 메서드에서 숫자가 아닌 배열을 인수로 전달하면 최대값을 할 수 없으므로 NaN을 반환한다.
const newMax = Math.max(...arr) // 3
// 스프레드 문법을 사용하면 배열 arr값을 펼쳐서 1,2,3으로 받고 이 중 최대값인 3을 반환한다.
const anotherNewMax = Math.max.apply(null, arr); // 3
// 스프레드 문법이 제공되기 이전에는 apply 메서드를 사용했다. (알아둘 필요는 없을듯?)
⚡️ 주의할 점
Rest 파라미터와 형태가 동일하니 혼동하지 않도록 주의하자.
- Spread 문법은 이터러블을 펼쳐서 개별적인 값들의 목록을 만드는 것.
- Rest 파라미터는 함수에 전달된 인수들의 목록을 배열로 전달받기 위한 것 (얘는 매개변수 앞에
...
을 붙여서 사용)
function sum(...theArgs) {
return theArgs.reduce((previous, current) => {
return previous + current;
});
}
sum(1,2,3) // 6
sum(1,2,3,4) // 10
배열 리터럴 내부에서 사용하는 경우
스프레드 문법을 사용하면 더 간결하고 가독성 좋게 표현할 수 있다.
- concat
const arr = [1,2].concat([3,4]);
console.log(arr); // [1, 2, 3, 4]
// concat을 사용해도 좋지만 더 간결하게 스프레드 문법을 사용해보자
const arr2 = [...[1, 2], ...[3, 4]];
console.log(arr2); // [1, 2, 3, 4]
- splice
// splice는 어떤 배열 중간에 다른 배열의 요소들을 추가하거나 제거할 때 사용하는 메서드이다.
const arr1 = [1, 4];
const arr2 = [2, 3];
arr.splice(1, 0, arr2); // 기대한 결과가 [1, 2, 3, 4]였으나 실제는 다르다/
console.log(arr1); // [1, [2, 3], 4]
이를 스프레드 문법을 사용하면 간단해진다.
arr.splice(1, 0, ...arr2); // 위 splice에서 원본 배열이 바뀐건 생략했지만 항상 명심하자
console.log(arr1); [1, 2, 3, 4] // splice는 원본 배열을 직접 변경하는 메서드다.
- slice
const origin = [1, 2];
const copy = origin.slice();
console.log(copy); // [1, 2]
console.log(copy === origin); // false
// 스프레드 문법을 사용하면 더 간결하고 가독성 좋게 표현 가능하다.
const origin2 = [1, 2];
const copy2 = [...origin];
console.log(copy2); // [1, 2]
console.log(copy2 === origin2); // false
- 이터러블을 배열로 변환
function sum() {
var args = Array.prototype.slice.call(arguments);
return args.reduce(function (pre, cur) {
return pre + cur;
}, 0);
}
console.log(sum(1, 2, 3)); // 6
// 스프레드 문법을 사용하면 더 간결해진다.
function sum() {
return [...arguments].reduce((pre, cur) => pre + cur, 0);
}
console.log(sum(1, 2, 3)); // 6
객체 리터럴 내부에서 사용하는 경우
const obj = { x: 1, y: 2 };
const copy = { ...obj }; // 스프레드 프로퍼티
console.log(copy); // { x: 1, y: 2 }
console.log(obj === copy); // false (얕은 복사)
// 객체 병합
const merged = { x: 1, y: 2, ...{ a: 3, b: 4 } };
console.log(merged); // { x: 1, y: 2, a: 3, b: 4 }
const merged2 = { ...{ x: 1, y: 2 }, ...{ y: 10, z: 3 } };
console.log(merged2); // { x: 1, y: 10, z: 3 }