javascript

[ES6] Spread Operator(...)

Bittersweet- 2022. 7. 12. 11:30
728x90

ES6 부터 등장한 Spread Operator는 점 3개가 연달아 붙어 있는 표시로 mdn에서는 전개구문으로 검색 시 결과를 확인할 수 있으며, 배열, 함수, 객체 등을 다루는 데 있어서 새로운 기능을 제공한다.

 

기본 문법

스프레드 연산자를 사용하면 배열, 문자열, 객체 등 반복 가능한 객체(Iterable Object)를 개별요소로 분리할 수 있다.

// Number
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [...arr1, 6, 7, 8, 9];

console.log(arr2); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

// String
const str1 = "bitter sweet";
const str2 = [...str1];

console.log(str2); // ["b", "i", "t", "t", "e", "r", " ", "s", "w", "e", "e", "t"]

 

 


배열에서 사용법

1. 배열 병합

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

// 기존
const arr = arr1.concat(arr2);

// ES6
const arr = [...arr1, ...arr2];
// or
const arr = arr1.push(...arr2);

console.log(arr); // [1,2,3,4,5,6]

 

2. 배열 복사

- 배열 참조

* Javascript에서 배열을 새로운 변수에 할당하는 경우 새로운 배열은 기존 배열을 참조한다. 그러므로 새로운 배열 변경 시 원본 배열도 함께 변경된다.

// 단순 변수 할당
const arr1 = ['Amy', 'John'];
const arr2 = arr1;

arr2.push('Sparkle');
console.log(arr2); // ['Amy, 'John', 'Sparkle']
// 원본 배열도 함께 변경
console.log(arr1); // ['Amy', 'John', 'Sparkle']

- 배열 복사

// ES6 이전
// 1. slice
const arr1 = ['Amy', 'John'];
const arr2 = arr1.slice();
arr2.push('Sparkle');
console.log(arr2); // ['Amy', 'John', 'Sparkle']
// 원본 배열은 변경되지 않음
console.log(arr1); // ['Amy', 'John']

// 2. ES5 map
const arr3 = arr1.map((item) = > item);
arr3.push('Sparkle');
console.log(arr3); // ['Amy', 'John', 'Sparkle']
// 원본 배열은 변경되지 않음
console.log(arr1); // ['Amy', 'John']


// ES6
const arr4 = [...arr1];
arr4.push('Sparkle');
console.log(arr4); // ['Amy', 'John', 'Sparkle']
// 원본 배열은 변경되지 않음
console.log(arr1); // ['Amy', 'John']

Spread 연산자를 이용한 복사는 얕은(shallow) 복사를 수행하며, 배열 안에 객체가 있는 경우에는 객체 자체는 복사되지 않고 원본값을 참조한다. 따라서 원본 배열 내의 객체를 변경하는 경우 새로운 배열 내의 객체 값도 변경된다.

const arr1 = [{name: 'Amy', age: 10}];
const arr2 = [...arr1];

arr2[0].name = 'John';

console.log(arr1); // [{name: 'John', age: 10}]
console.log(arr2); // [{name: 'John', age: 10}]

 


 

함수에서의 사용법

1. Rest Parameter

함수를 호출할 때 함수의 매개변수(Parameter)를 Spread Operator로 작성한 형태를 Rest 파라미터라고 한다. Rest 파라미터를 사용하면 함수의 파라미터로 오는 값들을 모아서 "배열"로 만든다.

function add(...rest) {
  let sum = 0;
  for(let item of rest) {
    sum += item;
  }
  return sum;
}

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

위의 예시를 보면 Rest 파라미터를 이용해 인자의 개수와 상관없이 모든 인자의 합을 구하는 함수를 간편하고 구현할 수 있었다.

기본 인자와 함께 섞어서도 사용할 수 있다.

function addMultiple(method, ...rest) {
  if(method === "add") {
    let sum = 0;
    for(let item of rest) {
      sum += item;
    }
    return sum;
  } else if(method === "mulitple") {
    let mul = 1;
    for(let item of rest) {
      mul *= item;
    }
    return mul;
  }
}

console.log(addMultiple('add', 1,2,3,4)); // 10
console.log(addMultiple('multiple', 1,2,3,4)); // 24

 

2. 함수 호출 인자로 사용

함수를 call할 때에도 Spread Operator를 사용할 수 있다. 기존에는 배열로 되어 있는 내용을 함수의 인자로 넣어주려면 직접 풀어서 넣어주던지 Apply를 이용했어야 하지만 Spread Operator를 이용하면 배열의 형태에서 바로 함수 인자로 넣어줄 수 있다.

// 기존 Apply
function sum (x,y,z) {
  return x + y + z;
}
const numbers = [1, 2, 3]
console.log(sum.apply(null, numbers));

// ES6
// 예시 1. Math
const numbers = [9,4,7,1];
Math.min(...number); // 1

// 예시 2. Map
const input = [{name:'철수', age: 12}, {name:'영희', age: 12}, {name:'바둑이', age: 2}];
const minAge = Math.min(...input.map((item) => item.age) );
console.log(minAge); // 2

 


 

객체에서의 사용법(* ES2018(ES9)에서 추가)

1. 객체 복사 또는 업데이트

객체에서 Spread Operator를 이용하여 복사 또는 프로퍼티를 업데이트 할 수 있다. 간단한 State Management 구현을 위해 이 방법을 응용하여 사용하기도 한다.

let currentState = {name: '철수', gender: '남자'};
currentState = {...currentState, age: 10};

console.log(currentState); // {name: '철수', gender: '남자', age: 10}

currentState = {...currentState, name: '영희', gender: '여자'}
console.log(currentState); // {name: '영희', gender: '여자', age: 10}

두번째 currentState는 객체의 프로퍼티를 오버라이드 하여 객체가 업데이트가 되는 것을 확인할 수 있다.

 


 

구조분해 할당(destructuring Assignment)

Spread Operator는 배열이나 객체에서의 구조분해 할당에 사용될 수 있다. 이 경우, 의미적으로 Spread Operator보다는 rest 파라미터에 가까운 형태가 된다.

let a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(rest); // [30, 40, 50]

({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}

 

 


 

클린한 코드를 지향하는 개발자들로써는 ES6에 도입된 Spread Operator가 은근 손이 많이 갈 수 밖에 없다고 생각된다. 이런저런 응용이 가능하므로 현재 프론트엔드를 하고 있거나 하기 위해 준비 중이신 분이라면 꼭 알아두는 것이 유용할 것 같습니다~

'javascript' 카테고리의 다른 글

part 2. Promise 사용법  (0) 2022.07.14
Part 1. Promise란? (작동 방식)  (0) 2022.07.14
배열의 중복 제거  (0) 2022.06.23
정규식 모음  (0) 2022.06.03
RegEX 정규 표현식(Regular Expression)  (0) 2022.06.03