본문 바로가기
Understanding JavaScript

[JS] What is Spread Operator, Rest Parameter?(스프레드 연산자, 나머지 매개변수란 무엇인가?)

by Luciditas 2023. 1. 3.
728x90

Spread Operator란?

하나로 뭉쳐있는 여러 값들의 집합을 펼쳐서 개별적인 값들의 목록으로 만드는 것을 말한다.

"..."으로 표현한다. 

편하게 생각하면 괄호를 제거해주는 역할을 한다.

Spread Operator를 사용할 수 있는 대상은 Array,String, Map, DOM collection(NodeList, HTMLCollection, arguments)와 같이 for...of문으로 순회할 수 있는 이터러블에 한정된다.

console. log(...[1, 2, 3]); // (1, 2, 3)

// 문자열은 이터러블이다.
console. log(...['Hello']); // H e l l o

// Map이나 Set은 이터러블이다.
console. log(...New Map([['a', '1']. ['b', '2']])); // ['a', '1]' ['b', '2']
console. log(...NEw Set[1, 2, 3]); // 1, 2, 3

위 예제 코드에서 ...[1, 2, 3]은 이터러블인 배열을 펼쳐서 요소들을 개별적인 값들의 목록인 1 2 3으로 만들어준다.

이때 1 2 3은 값이 아니라 값들의 목록이다.

여기서 Spread문법 ...이 피연산자를 연산하여 값을 생성하는 연산자가 아니라는 것을 알수 있다.

따라서 스프레드 문법의 결과는 변수에 할당할 수 없다.

 

Spread Operator를 언제 사용하는 걸까?

 

배열을 합치거나 복사할때

let arr1 = [1,2,3]
let arr2 = [4,5,6,7]

위 예시 코드에서 arr1과 arr2의 요소를 모두 가진 배열을 하나 만들고 싶다면 어떻게 해야할까?

가장 간단한 방법으로는 새로운 변수를 선언하여 arr1의 요소와 arr2의 요소가 모두 넣어주면 될 듯하다.

하지만 Spread Operator를 사용하여 만들 수도 있다.

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

let newArr = [...arr1 , ...arr2];

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

또한 배열을 복사할 때도 Spread Operator를 이용한다.

// a를 새로운 변수 b에 직접 할당하는 경우

let a = [1,2,3];
let b = a;

배열은 참조 자료형이기 때문에 위와 같이 변수를 할당하면 값의 공유가 일어난다.

따라서 a 배열의 요소를 변경하면 b의 값도 변경된다.

이 때 Spread Operator를 사용하면 이러한 문제를 해결할 수 있다.

// 배열을 복사 해온 경우

let a = [1,2,3];
let b = [...a];

a를 새로운 변수에 직접 할당할 때와 위 예시 코드에서의 값을 출력해보면 모두 [1,2,3]으로 나올 것이다.

하지만 위 예시 코드에서는 a의 요소를 변경한다 하더라도 b에는 영향을 주지 않는다.

 

이러한 Spread Operator는 객체들을 합치거나 객체를 복사할 때도 사용할 수 있다.

let obj1 = [a:1, b:2];
let obj2 = [c:3, d:4];

위 예시 코드에서 obj1과 obj2를 합치고 싶다면 어떻게 해야할까?

배열과 마찬가지로 가장 간단한 방법은 새로운 변수를 선언한 후 obj1과 obj2의 값들을 직접 넣으면 될 것이다.

그렇지만 Spread Operator를 사용하여 이 두 객체를 합친 새로운 객체를 만들 수 있다.

let obj1 = {a:1, b:2};
let obj2 = {c:3, d:4};

let obj3 = {...obj1, ...obj2};

console.log(obj3) // {a:1, b:2, c:3, d:4}

그런데 만약 객체의 key 값에 중복이 일어난다면 어떻게 될까?

let obj1 = {a:1, b:2};
let obj2 = {a:3, d:4};

let obj3 = {...obj1, ...obj2};

console.log(obj3) // {a:3, b:2, d:4}

만약 두 객체에서 key 값에 중복이 일어난다면 나중에 들어오는 key의 value가 우선한다.

위 예시코드에서는 a : 1 보다 a : 3이 나중에 들어오므로 obj3의 값은 {a : 3, b : 2, d : 4}가 된다.

 

 

 

Rest Parameter

Rest parameter는 외형상으로는 Spread문법과 유사한 면이 있다.

하지만 Rest parameters는 파라미터를 배열의 형태로 받아서 사용할 수 있는 특징이 있다. 

따라서 파라미터 개수가 가변적일 때 유용하게 사용할 수가 있다.

function example(...args){
	console.log(args)
}
example(1,2,3,4,5,6,7);

위의 예시 코드를 출력하면 다음과 같은 결과를 알 수 있다.

위에서 rest parameter에 대한 특징을 정리했던 것처럼 파라미터를 배열의 형태로 받을 수 있다.

function example (a, b, ...args) {
    console.log(args)
}

example(1,2,3,4,5,6,7);

그렇다면 위의 코드처럼 작성하면 어떤 결과가 나올까?

 

위 이미지처럼 앞의 두 파라미터를 제외한 3,4,5,6,7을 배열의 형태로 받는다.

이처럼 파라미터의 종류가 많을 경우 유용하다.

 

Rest parameter사용시 주의할 점

Rest parameter는 '나머지 매개변수'라는 말처럼 매개변수들 중 가장 마지막에 작성해야한다.

function example (a, b, ...args) {
    console.log(args)
}

example(1,2,3,4,5,6,7);

위 코드를 보면 매개변수 a, b뒤에 Rest parameters를 작성했다.

 

또한 Rest parameter는 2개 이상 사용할 수 없다.

function example (a, b, ...args, ...argw2) {
    console.log(args)
}

example(1,2,3,4,5,6,7);

위 예시 코드는 Rest parameter를 2개 사용하고 있다.

[이미지] Rest parameter를 2개 이상 사용하면 SyntaxError를 발생시킨다.

 

따라서 Rest parameter는 매개변수 중 가장 마지막에 한 번만 쓸 수 있는 것을 기억하도록 하자.

 

728x90