ECMAScript | TypeScript

ECMAScript6, Spread Operator

partner_jun 2018. 6. 1. 15:48

전개 연산자(Spread Operator)는 배열, 제네레이터 함수 등의 이터레이터를 펼쳐내는 연산자다. Rest Parameter와 마찬가지로 변수 앞에 ...를 붙이면 된다.


const arr1 = ["hello", "world", "!!!"];
console.log(...arr1); // hello world !!!

console.log 함수는 1개 이상의 파라미터를 받는 함수다.



더 다양한 함수에 사용해 보자.

const input = ['hello', 'jack'];

const func1 = (str) => console.log('func1', str);
func1(input); // func1 ['hello', 'jack']
// func1(...input); // Error

const func2 = (...str) => console.log('func2', str);
func2(input); // func2 [ ['hello', 'jack'] ]
func2(...input); // func2 ['hello', 'jack']

// TypeScript에서는 불가능
const func3 = (msg, name) => console.log('func3', msg);
func3(input); // func3 ["hello", "jack"]
func3(...input); // func3 hello

변수에 Spread Operator를 사용하면 변수의 내용이 '풀어진' 상태로 전달되는 것을 확인할 수 있다.




Object에도 사용할 수 있다.

const simpleUser = {name: 'Jack', age: 20};
const userDetail = {...simpleUser, city: 'Seoul', job: 'SW Engineer'};

// const arr = [...userDetail]; // Error
console.log(userDetail); // {name: "Jack", age: 20, city: "Seoul", job: "SW Engineer"}

userDetail 객체에 simpleUser의 프로퍼티들이 선언된 것을 확인할 수 있다.



Destructuring 문법에서도 사용할 수 있다.

const [input, ...params] = ['/join', 'jack', 'admin'];

console.log(input, params); // /join ['jack', 'admin']

params 변수는 나머지 값들을 가지는 '배열'이 되었다.



제네레이터 함수도 Spread Operator로 풀어낼 수 있다.

function* getNumbers() {
let numb = 0;
while(numb < 10) {
yield numb += 2;
}
}

// ECMA6 (TypeScript에서는 불가능)
console.log(...getNumbers()); // 2 4 6 8 10



하지만 TypeScript에서 Generator 객체에 Spread Operator를 적용하는 것은 불가능하다. 타입 문제인지 아직 지원하지 않는 것인지는 모르겠지만, 확실한 것은 적용이 가능하다면 아래와 같은 문제가 발생할 수 있다는 것이다.

function* infinityGenerator() {
let i=0;

while(true) {
yield i++;
}
}

console.log(...infinityGenerator()); // Crash!

위 예제를 실행하면 브라우저가 크래시된다!



이 몇가지 예제를 통해 Spread Operator는 flatten의 특성을 가진다는 것을 알 수 있다. 이터레이터에 Spread Operator를 적용하면 변수를 풀어낸 형태가 되지만 '담는 방법에 대해서는 정해지지 않은' 상태인 것이다.