🚀 94sssh
Published on

2024.08.22

[딥다이브] - 35. 스프레드 문법

ES6에서 도입된 스프레드 문법 ...은 여러 값들의 집합을 펼쳐 개별적인 값의 목록으로 만든다.
스프레드 문법의 결과물은 값이 아니므로 값의 목록을 사용하는 문맥에서만 사용할 수 있다.

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

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

요소들의 집합인 배열을 펼쳐서 개별적인 값들의 목록으로 만든 후, 함수의 인수 목록으로 전달할 때 사용할 수 있다.
이전에는 Function.prototype.apply를 사용했지만, 스프레드 문법이 더 간결하고 가독성이 좋다.

const arr = [1, 2, 3]

const max = Math.max(...arr) // 3

스프레드 문법은 Rest 파라미터와 형태가 동일해 혼동할 수 있는데, 둘은 서로 반대의 개념이다.

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

ES5에서 사용하던 방식과 비교하여 보자.

35.2.1. concat

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

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

35.2.2. splice

// ES5
var arr1 = [1, 4]
var arr2 = [2, 3]

Array.prototype.splice.apply(arr1, [1, 0].concat(arr2))
console.log(arr1) // [1, 2, 3, 4]

// ES6
const arr1 = [1, 4]
const arr2 = [2, 3]

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

35.2.3. 배열 복사

// ES5
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

35.2.4. 이터러블을 배열로 변환

// ES5
function sum() {
  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

// 이터러블이 아닌 유사 배열 객체
Array.from(arrayLike)

35.3. 객체 리터럴 내부에서 사용하는 경우

Rest 프로퍼티와 함께 스프레드 프로퍼티를 사용하면 일반 객체를 대상으로도 스프레드 문법의 사용을 허용한다.

// 스프레드 프로퍼티
// 객체 복사(얕은 복사)
const obj = { x: 1, y: 2 }
const copy = { ...obj }
console.log(obj) // { 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 }