스프레드 문법 (Spread syntax, 전개문법)
ES6에서 새롭게 도입된 문법 …은 하나로 뭉쳐있는 여러 값들의 집합을 펼쳐서 개별적인 값들의 목록을 만든다.
Array, String, Map, Set, Dom 컬렉션(NodeList, HTMLCollection), Arguments와 같이 for…in문으로 순회할 수 있는 이터러블에 한정된다.
1 2 3 4 5
| console.log(...[1, 2, 3]) console.log(...'young');
console.log(... { a: 1, b: 2});
|
- 스프레드 문법의 결과는 값이 아니라 값들의 목록이다.
- 값이 아니라 변수에 할당할 수 없다.
- 연산하여 값을 생성하는 연산자도 아니다.
- 결과물은 단도그로 사용할 수 없다.
- 쉼표로 구분한 값의 목록을 사용하는 문에서 사용된다.
- 함수 호출문의 인수 목록
- 배열 리터럴의 요소 목록
- 객체 리터럴의 프로퍼티 목록 (Stage 4)
1. 함수 호출문의 인수 목록에서 사용하는 경우
- Math.max 메소드에 숫자가 아닌 배열을 인수로 전달하면 최대값을 구할 수 없다 (NaN)
- 이를 위해 Function.prototype.apply 사용
- 위 메소드보다 스프레드 문법이 간결하고 가독성이 좋다.
1 2 3
| const arr = [1, 2, 3]; const maxValue = Math.max(...arr); console.log(maxValue);
|
- Rest 파라미터와 혼동 주의
- Rest 파라미터 - 함수에 전달된 인수들의 목록을 배열로 전달받기 위해 매개 변수 이름 앞에 …
- 스프레드 문법 - 배열같은 이터러블을 펼쳐서 개별적인 값들의 목록을 만드는 것
2. 배열 리터럴 내부에서 사용하는 경우
ES5에서 사용하던 방식과 비교
2.1 concat
기존의 배열 요소들을 새로운 배열의 일부로 만들고 싶은 경우
1 2 3 4 5 6
| var arr = [1, 2].concat([3, 4]); console.log(arr);
const arr = [...[1, 2], 3, 4]; console.log(arr);
|
2.2 push
기존의 배열에 다른 배열의 요소들을 push
1 2 3 4 5 6 7 8 9 10 11 12 13
| var arr1 = [1, 2]; var arr2 = [3, 4];
Array.prototype.push.apply(arr1, arr2); console.log(arr1);
const arr1 = [1, 2]; const arr2 = [3, 4];
arr1.push(...arr2);
console.log(arr1);
|
2.3 splice
기존의 배열에 다른 배열의 요소들을 삽입
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var arr1 = [1, 4]; var arr2 = [2, 3];
Array.prototype.splice.apply(arr1, [1, 0].concat(arr2));
console.log(arr1);
const arr1 = [1, 4]; const arr2 = [2, 3];
arr1.splice(1, 0, ...arr2); console.log(arr1);
|
2.4 배열 복사
기존의 배열을 복사하기 위해서는 slice 메소드를 사용
배열의 각 요소를 얕은 복사하여 새로운 복사본 생성
1 2 3 4 5 6 7 8 9 10 11 12
| var = origin = [1, 2]; var copy = origin.slice();
console.log(copy); console.log(copy === origin);
const origin = [1, 2]; const copy = [...origin];
console.log(copy); console.log(copy === origin);
|
2.5 유사 배열 객체를 배열로 변환
유사 배열 객체를 배열로 변환하려면 slice메소드를 apply 함수로 호출
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function sum () { var args = Array.pototype.slice.apply(arguments);
return args.reduce(function (pre, cur) { return pre + cur; }, 0); }
console.log(sum(1, 2, 3));
function sum () { const args = [...arguments];
return args.reduce((pre, cur) => pre + cur, 0); }
console.log(sum(1, 2, 3));
|
3. 객체 리터럴 내부에서 사용하는 경우
TC39 프로세스의 stage 4 단계에 제안되어 있다.
스프레드 문법은 이터러블이여야 하지만 스프레드 프로퍼티 제안은 일반 객체를 대상으로도 스프레드 문법의 사용을 허용한다.
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 32 33 34 35 36 37 38 39 40 41
| const obj = { x: 1, y: 2}; const copy = { ...obj }; console.log(copy); console.log(obj === copy);
const merged = { x: 1, y:2, ... { a: 3, b: 4 } }; console.log(merged); { x: 1, y: 2, a: 3, b: 4 };
const merged = Object.assign({}, { x: 1, y: 2 }, { y: 10 , z: 3 }); console.log(merged);
const changed = Object.assign({}, { x: 1, y: 2 }, { y: 10 }); console.log(changed);
const added = Object.assign({}. { x: 1, y: 2 }, { y: 10 , z: 0 }); console.log(added);
const merged = { ...{ x: 1, y: 2 }, ... { y: 10 , z: 3 }); console.log(merged);
const changed = { ...{ x: 1, y: 2 }, { y: 10 }); console.log(changed);
const added = { ...{ x: 1, y: 2 }, { z: 0 }); console.log(added);
|