Spread operator (...)

Juyeon Lee·2022년 2월 3일
0

배열은 모든 요소를 spread operator로 풀어서 새로운 배열에 넣는 방법은 아래와 같다.

const arr = [7, 8, 9];
const badNewArr = [1, 2, arr[0], arr[1], arr[2]];
console.log(badNewArr);

const newArr = [1, 2, ...arr];
console.log(newArr); // [1, 2, 7, 8, 9]

이미 존재하는 배열에 다른 배열의 원소들을 하나씩 넣어주고 싶으면 위의 코드에 badNewArr처럼 일일이 원소들을 넣어주는 것도 가능하지만 간편하게 spread opertaor를 사용할 수 있다. ...arr이라고 써주면 arr 배열에 들어있는 7,8,9가 원소로 들어가게 되는 것이다. 여기서 ...를 빼고 arr만 써주면 arr 자체가 배열의 한 요소로 들어가게 된다.

const newMenu = [...restaurant.mainMenu, 'Gnocci'];
console.log(newMenu);

위의 코드처럼 newMenu라는 배열에 restaurant.mainMenu의 원소들이 차례로 들어가고 그 뒤에 'Gnocci'가 배열에 추가된다. 이때 다른 배열에 'Gnocci'와 같이 추가되었다고 해도 원래의 restaurant.mainMenu 배열은 변형되지 않는다.

destructuring과 spread operator의 다른점

Spread 연산자는 배열의 모든 요소를 가져온다. 새로운 변수를 생성하지 않고, 쉼표로 구분된 값이 필요한 곳에서만 사용할 수 있다.

배열, 문자열, map, set은 iterable 객체(반복 가능한 것들)이지만, 일반객체는 iterable이 아니다. Spread 연산자는 iterable 객체에 사용할 수 있다. 문자열도 iterable이기 때문에 다음과 같은 코드가 가능하다.

const str = 'Jonas';
const letters = [...str, '', 'S.'];
console.log(letters);

하지만 다음과 같은 코드는 불가능하다.

console.log(`${...str} Lee`);

그 이유는 쉼표로 구분된 여러 값은 함수에 인수로 전달할 때나 새로운 배열을 만들 때만 사용되기 때문이다

그럼 spread operator를 함수에 인수로 전달하는 예시를 한 번 살펴보도록 하자.

orderPasta: function (ing1, ing2, ing3) {
    console.log(
      `Here is your delicious pasta with${ing1},${ing2} and ${ing3}`);
  }

위와 같은 함수를 추가한 뒤

const ingredients = [
  prompt("Let's make pasta! Ingredients 1?"),
  prompt('Ingredients 2?'),
  prompt('Ingredients 3'),
];

이렇게 Ingredient 값을 받아온 다음,

restaurant.orderPasta(ingredients[0], ingredients[1], ingredients[2]);

or

restaurant.orderPasta(...ingredients);

이렇게 함수를 호출하면 된다. 위에 객체는 iterable하지 않다고 썼는데, 이 부분이 잘 이해가 가지 않아서 검색해본 결과, 다음과 같이 이해하면 된다. spread operator를 쓸 수 있다는 건 결국 내부에서 반복자를 사용해 원소들을 하나씩 추출하는 것이기 때문에 iterable 객체에서만 적용될 수 있다. 그래서 예를 들어 배열은 그게 가능하지만 일반 객체는 아래와 같이 안에 있는 원소들을 풀어서 뽑아 줄 수 없다.

const obj = { a: 1, b: 2 };
console.log(...obj); // Error: obj is not iterable

즉 위의 코드와 같이 객체로 되어있는걸 ...obj로 풀어서 써줄 수 없다는 것이다.

그런데 ES2018부터 object에서 spread operator를 쓸 수 있게 되었는데, 여기서 위의 예시처럼 객체 자체를 풀어서 쓸 수 있다는 것이 아니라, 객체 안의 속성을 복사하거나 합칠 때 사용한다. 예를 들어 아래의 코드를 보자.

const newRestaurant = { foundedIn: 1998, ...restaurant, founder: 'Juyeon' };
console.log(newRestaurant);

이렇게 쓰면 restaurant이라는 객체에 foundedIn과 founder라는 속성을 추가해 합쳐 줄 때 spread operator를 쓰는걸 볼 수 있다.속성을 복사하는 것도 아래와 같이 가능하다.

const restaurantCopy = { ...restaurant };
restaurantCopy.name = 'Ristorante Roma';
console.log(restaurantCopy.name);
console.log(restaurant.name);

이렇게 restaurant 객체를 restaurantCopy라는 이름으로 복사해준 뒤, 복사한 객체에 name 속성을 추가해 줄 수 있다.

0개의 댓글