스프레드 문법이 제공되기 전에는 Function.prototype.apply를 사용했다. 하지만, 스프레드를 사용한다면 가독성이 더 좋다.
var arr = [1,2,3];
var max1 = Math.max.apply(null,arr); // 3
var max2 = Math.max(...arr);
스프레드 문법은 Rest 파라미터와 형태가 동일하여 혼동할 수 있다. 둘은 서로 반대의 개념이므로 잘 구분하자.
function foo(...rest){
console.log(rest); // 1,2,3 -> [1,2,3]
}
foo(...[1,2,3]); // [1,2,3] -> 1,2,3
2개의 배열을 1개로 결합하고 싶은 경우 사용한다.
//ES5
var arr = [1,2].concat([3,4]);
console.log(arr);
//ES6
const arr = [...[1,2], ...[3,4]];
console.log(arr); // [1,2,3,4]
배열의 중간에 다른 배열의 요소들을 추가하거나 제거하기 위해 사용한다.
//ES5
var arr1 = [1,4];
var arr2 = [2,3];
// 세 번째 인수 arr2를 해체하여 전달하지 않으면 arr1에 arr2 배열 자체가 추가된다.
arr1.splice(1,0,arr2);
console.log(arr1); // [1,[2,3],4]
Array.prototype.splice.apply(arr1,[1,0].concat(arr2));
console.log(arr1); // [1,2,3,4]
//ES6
arr1.splice(1,0,...arr2);
console.log(arr); // [1,2,3,4]
splice를 사용해 배열을 복사할 수도 있다.
배열 복사시 원본 배열의 각 요소를 얕은 복사하여 새로운 복사본을 생성한다.
var origin = [1,2];
var copy = origin.slice();
console.log(copy) // [1,2]
console.log(copy === origin); // false
var origin = [1,2];
var copy = [...origin];
console.log(copy) // [1,2]
console.log(copy === origin); // false
얕은 비교
원시타입 데이터의 경우 값이 동일한지만 비교하고, 객체타입 데이터의 경우 참조만 비교한다.
const o1 = { id: 1 };
const o2 = { id: 1 };
console.log(o1 === o2); // false
깊은 비교
객시 타입의 데이터도 값으로 비교한다.
const o1 = { id: 1 };
const o2 = { id: 1 };
console.log(JSON.stringify(o1) === JSON.stringify(o2)); // true
ES5에서 이터러블을 배열로 변환하려면 Function.prototype.apply 또는 Function.prototype.call 메서드를 사용하여 slice 메서드를 호출해야 한다. 스프레드 문법과 Rest 파라미터를 사용해서 더 간편하게 변환도 가능하다.
function sum(){
// 이터러블이면서 유사 배열 객체인 arguments를 배열로 변환
var args = Array.prototype.slice.call(arguments);
return args.reduce(function (pre, cur){
return pre + cur;
},0);
}
//스프레드 문법
function sum(){
return [...arguments].reduce((pre, cur) => pre + cur, 0);
}
//Rest 파라미터
const sum = (...args) => args.reduce((pre, cur) => pre + cur, 0);
console.log(sum(1,2,3)); // 6
유사 배열 객체도 배열로 변환할 수 있다.
const arrayLike = {
0:1,
1:2,
2:3,
length:3,
}
const arr1 = Array.prototype.slice.call(arrayLike); // [1,2,3]
console.log(Array.isArray(arr1)); // true
const arr2 = [...arrayLike]; // TypeError (유사 배열 객체는 스프레드 문법의 대상이 아니다.)
//Array.from을 사용해 유사 배열 객체 또는 이터러블을 배열로 변환한다.
Array.from(arrayLike); // [1,2,3]
스프레드 프로퍼티를 사용하면 객체 리터럴의 프로퍼티 목록에서도 스프레드 문법을 사용할 수 있다. 스프레드 문법의 대상은 이터러블이어야 하지만 스프레드 프로퍼티 제안은 일반 객체를 대상으로도 스프레드 문법의 사용을 허가한다.
// 스프레드 프로퍼티
// 객체 복사(얕은 복사)
const obj = { x:1, y:2 };
const copy = { ...obj };
console.log(copy); // { x:1, y:2 }
console.log(copy === obj); // false
//객체 병합
const merged = { x:1, y:2, ...{ a:3, b:4 }};
console.log(merged); // { x:1, y:2, a:3, b:4 }
스프레드 프로퍼티가 제안되기 이전에는 Object.assign 메서드를 사용하여 객체의 병합 및 특정 프로퍼티 변경, 추가가 가능했다.
// Object.assign 객체 병합
const merged = Object.assign({},{ x:1, y:2 }, { y:10, z:3 }); // { x:1, y:10, z:3 }
// Object.assign 특정 프로퍼티 변경
const changed = Object.assign({},{ x:1, y:2 }, { y:100 });
console.log(changed); // { x:1,y:100 }
// Object.assign 특정 프로퍼티 추가
const added = Object.assign({},{ x:1, y:2 }, { z:0 });
console.log(added); // { x:1, y:2, z:0 }
스프레드 프로퍼티를 활용해 Object.assign 메서드를 대체할 수 있다.
// 객체 병합
const merged = { ...{ x:1, y:2 }, ...{ y:10, z:3 }}; // { x:1, y:10, z:3 }
// 특정 프로퍼티 변경
const changed = { ...{ x:1, y:2 }, y:100 };
console.log(changed); // { x:1,y:100 }
// 특정 프로퍼티 추가
const added = { ...{ x:1, y:2 }, z:0 };
console.log(added); // { x:1, y:2, z:0 }