Javascript 스프레드 문법

fgStudy·2022년 4월 26일
0

자바스크립트

목록 보기
14/26
post-thumbnail

해당 포스팅에서 자바스크립트의 스프레드 문법에 대한 정의와 사용처를 ES5때와 비교해보고자 한다.


스프레드 문법 정의

스프레드 문법(...)은 하나로 뭉쳐져 있는 여러 값들의 집합을 펼쳐서 개별적인 값들의 목록으로 만든다. 스프레드 문법을 사용할 수 있는 대상은 이터러블에 한정된다.

스프레드 문법의 결과값은 아래의 쉼표로 구분한 값의 목록을 사용하는 문맥에서만 사용될 수 있다.

  • 함수 호출문의 인수 목록
  • 배열 리터럴의 요소 목록
  • 객체 리터럴의 프로퍼티 목록

1. 함수 호출문의 인수 목록에서 사용하는 경우

스프레드 문법은 요소들의 집합인 배열을 펼쳐서 개별적인 값들을 목록으로 만든 다음 함수의 인수 목록으로 전달할 때 사용된다.

const arr = [1,2,3];
const max = Math.max(...arr); // 3

2. 배열 리터럴 내부에서 사용하는 경우

스프레드 문법을 배열 리터럴에서 사용하면 ES5보다 훨씬 간결하다.

2-1. 배열 결합

ES5에서 2개의 배열을 1개의 배열로 결합하고 싶은 경우 concat을 이용했다.

// ES5
var arr = [1,2].concat([3,4]);
console.log(arr); // [1,2,3,4]

ES6에서는 스프레드 문법을 이용해 배열 리터럴만으로 2개의 배열을 1개의 배열로 결합할 수 있다.

const arr = [...[1,2], ...[3,4]];
console.log(arr); // [1,2,3,4]

2-2. 배열 요소 추가

ES5에서 어떤 배열의 중간에 다른 배열의 요소들을 추가하거나 제거하기 위해 splice 메서드를 사용했다. 하지만 이 경우 배열 자체가 추가가 된다.

var arr1 = [1,4];
var arr2 = [2,3];

// 세 번째 인수 arr를 해체해서 전달해야 한다.
// 그렇지 않으면 arr1에 arr2 배열 자체가 추가된다.
arr1.splice(1,0,arr2);
console.log(arr1); // [1,[2,3],4]

스프레드 문법을 사용하면 아래와 같이 간결하게 표현할 수 있다.

const arr1 = [1,4];
const arr2 = [2,3];

arr1.splice(1,0, ...arr2);
console.log(arr1); // [1,2,3,4]

2-3. 배열 복사

ES5에서 배열을 (얕은)복사하려면 slice메서드를 사용한다.

var origin = [1,2];
var copy = origin.slice();

console.log(copy); // [1,2]
console.log(copy === origin); // false

ES6에서는 스프레드 문법을 통해 아래와 같이 구현할 수 있다.

const origin = [1,2];
const copy = [...origin];

console.log(copy); // [1,2]
console.log(copy === origin); // false

두 방법 모두 원본 배열의 각 요소를 얕은 복사하여 새로운 복사본을 만든다.


2-4. 이터러블을 배열로 변환

ES5에서 이터러블을 배열로 변환하려면 Function.prototype.apply 또는 Function.prototype.call 메서드를 사용하여 slice 메서드를 호출해야 한다.

function sum() {
  var args = Array.prototype.slice.call(argument);
  return args.reduce(function (pre, cur) {
  	return pre + cur;
  }, 0);
}

console.log(sum(1,2,3)); // 6

이 방법은 이터러블 뿐만 아니라 이터러블이 아닌 유사 배열 객체도 배열로 변환할 수 있다.

const arrayLike = {
  0: 1,
  1: 2,
  2: 3,
  length: 3
}

const arr = Array.prototype.slice.call(arrayLike); // [1,2,3]
console.log(Array.isArray(arr)); // true

스프레드 문법을 이용하면 이터러블을 간편하게 배열로 변환할 수 있다.

function sum() {
	return [...arguments].reduce((pre, cur) => pre+cur, 0);
}

console.log(sum(1,2,3)); // 6

단 이터러블이 아닌 유사배열객체는 스프레드 문법의 대상이 될 수 없다.

const arrayLike = {
  0: 1,
  1: 2,
  2: 3,
  length: 3
}

const arr = [...arrayLike]; // TypeError: arrayLike is not iterable

객체 리터럴 내부에서 사용하는 경우: 스프레드 프로퍼티

Rest 프로퍼티와 함께 스프레드 프로퍼티를 사용하면 객체 리터럴의 프로퍼티 목록에서도 스프레드 문법을 사용할 수 있다. 스프레드 문법의 대상은 이터러블이어야 하지만, 2021년 TC39 프로세스의 stage4 단계의 제안에 따르면 일반 객체를 대상으로도 스프레드 문법의 사용을 허용한다.

// 스프레드 프로퍼티
// 객체 복사 (얕은 복사)
const obj = {x:1, y:2};
const copy = {...obj};
console.log(copy); // {x:1, y:2}
console.log(obj === copy); // false

// 객체 병합
const merge = {x:1, y:2, ...{a:3, b:4}};
console.log(merge); // {x: 1, y: 2, a: 3, b: 4}

Object.assign 메서드 vs 스프레드 문법

스프레드 프로퍼티가 제안되기 이전에는 ES6에서 도입된 Object.assign 메서드를 사용하여 여러 개의 객체를 병합하거나 특정 프로퍼티를 변경 또는 추가했다.

// 1. 객체병합
// 프로퍼티가 중복되는 경우 뒤에 위치한 프로퍼티가 우선권을 갖는다.
const merged = Object.assign({}, {x:1, y:2}, {y:10, z:3});
console.log(merged); // {x: 1, y: 10, z: 3}

// 2. 특정 프로퍼티 변경
const changed = Object.assign({}, {x:1, y:2}, {y:10});
console.log(changed); // {x: 1, y: 10}

// 3. 프로퍼티 추가
const added = Object.assign({}, {x:1, y:2}, {z:0});
console.log(added); // {x: 1, y: 2, z: 0}

스프레드 프로퍼티는 Object.assign 메서드를 대체할 수 있다.

// 1. 객체병합
// 프로퍼티가 중복되는 경우 뒤에 위치한 프로퍼티가 우선권을 갖는다.
const merged = {...{x:1, y:2}, ...{y:10, z:3}};
console.log(merged); // {x: 1, y: 10, z: 3}

// 2. 특정 프로퍼티 변경
const changed = {...{x:1, y:2}, ...{y:10}};
console.log(changed); // {x: 1, y: 10}

// 3. 프로퍼티 추가
const added = {...{x:1, y:2}, ...{z:0}};
console.log(added); // {x: 1, y: 2, z: 0}

docs: 모던 자바스크립트 딥다이브 35강 스프레드 문법

profile
지식은 누가 origin인지 중요하지 않다.

0개의 댓글