코딩 공부/React

[React] ES6 객체와 배열 스프레드 연산자 [...] - 가온 코딩

Cosmic-dust 2022. 7. 23. 15:40
728x90
반응형

스프레드 연산자(spread operator)는 3개의 점(...)으로 이뤄진 연산자로, 몇 가지 다른 역할을 담당한다.

 

먼저, 스프레드 연산자를 사용해 배열의 내용을 조합할 수 있다.

ex) 두 배열이 있다면, 두 배열의 모든 원소가 들어간 세 번째 배열을 만들 수 있다.

 

 

1. 배열과 스프레드 연산자

// Spread Operator

// var peaks = ["Tallac", "Ralston", "Rose"]
// var canyons = ["Ward", "Blackwood"]
// var tahoe = [...peaks, ...canyons]

// console.log(tahoe.join(', '))
// "Tallac, Ralston, Rose, Ward, Blackwood"
 
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];


// arr2.reverse().forEach( (num)  => {
//   arr1.unshift(num);
// });

// console.log(arr1);
// 4, 5, 6, 1, 2, 3
// reverse 없이 실행할 경우: 6, 5, 4, 1, 2, 3

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

한글예시

//스프레드 연산자

const peaks = ["대청봉", "중청봉", "소청봉"];
const canyons = ["천불동계곡", "가야동계곡"];
const seoraksan = [...peaks, ...canyons];

console.log(seoraksan.join(', '));  // 대청봉, 중청봉, 소청봉, 천불동계곡, 가야동계곡

peacks와 canyons에 포함된 모든 원소가 seoraksan이라는 새 배열에 들어간다.

 

 

 

 

2. 배열에 reverse()를 적용한 후 구조 분해하기

앞의 예제에서 정의한 peaks 배열에서 마지막 원소를 변수에 담고 싶은 경우 어떻게 해야될까?

 

 

 

Array.reverse 메서드를 사용해 배열을 뒤집고 구조 분해를 사용해 첫 번째 원소를 변수에 넣으면 되지 않을까?

 

* 굳이 이렇게 시도하는 이유는?

 

- Array.reverse 메서드: 배열을 뒤집는 메서드

- 구조 분해: 객체 안에 있는 필드값을 원하는 변수 안에 넣을 수 있다.

 

리액트에서 내가 원하는 값을 얻으려고 할 때 웬만하면 원본의 값을 변형하지 않고 가져오는 게 좋다.

 

그런데 구조 분해는 배열의 위치를 알아야 넣을 수 있다(첫번째 위치, 두번째 위치, 세번째 위치 등..)

하지만 마지막 원소를 담고 싶은 경우에는 정확한 위치를 알 수가 없다. 마지막 원소가 10번째인지, 100번째인지 모르니까..

그래서 Array(배열).reverse(뒤집기) 를 사용해서 배열을 역순으로 바꾼 후, 첫 번째 위치값을 변수값에 저장하면, 우리가 원했던 마지막 원소를 변수에 담을 수 있는 것이다.

const b = ["대청봉", "중청봉", "소청봉"];
const [,,a] = b	// 구조분해

console.log(a); //소청봉
console.log(b.join(', ')); //대청봉, 중청봉, 소청봉

만약 마지막 원소의 위치값을 알 수 있다면, 위처럼 단순하게 구조 분해를 하면 될 일이다.

 

하지만 그것이 아니기 때문에 아래와 같은 방법을 쓴다.

 

// .reverse() mutates the peaks array

var peaks = ["Tallac", "Ralston", "Rose"]
var [last] = peaks.reverse() // ["Rose", "Ralston", "Tallac"]

console.log(last) 
console.log(peaks.join(', '))

한글예시

//스프레드 연산자. reverse를 넣는 경우

const peaks = ["대청봉", "중청봉", "소청봉"];
const [last] = peaks.reverse();

console.log(last); //소청봉
console.log(peaks.join(', ')); //소청봉, 중청봉, 대청봉

//reverse를 안 넣는 경우

const [last] = peaks

console.log(last); //대청봉
console.log(peaks.join(', ')); //대청봉, 중청봉, 소청봉

 

근데, 문제점이 있다!!

나는 마지막 원소 값을 얻고 싶었을 뿐이었는데, 배열이 뒤집히면 안되지 않을까?

그래서 나온 게 스프레드 연산자([...])이다.

 

3. 스프레드 연산자와 reverse(), 구조 분해 함께 사용하기

 

스프레드 연산자를 사용해 배열의 원소들을 복사했기 때문에, 원본인 p 는 변경되지 않고 그대로 남게 된다.

따라서 배열에는 영향을 미치지 않기 때문에 배열을 나중에도 그대로 사용할 수 있다.

 

 

const p = ["대청봉", "중청봉", "소청봉"];
const [l] = [...p].reverse();   // [...] 스프레드 연산자 사용

console.log(l); //소청봉
console.log(p.join(', ')); //대청봉, 중청봉, 소청봉

// duplicate peaks with spread and revers the duplicate

var peaks = ["Tallac", "Ralston", "Rose"]
var [last] = [...peaks].reverse()

console.log(last) // Rose
console.log(peaks.join(', '))

 

 

4. 스프레드 연산자와 구조 분해 함께 사용하기

스프레드 연산자를 사용해 배열의 나머지 원소들을 얻을 수도 있다.

 

 

const l = ["경포호", "화진포", "송지호", "청초호"];
const [f, ...r] = l;	// 처음 원소만 제외하고 나머지 값을 r에 넣기

console.log(r.join(", ")); // "화진포, 송지호, 청초호"

// Destructuring with the spread operator

var lakes = ["Donner", "Marlette", "Fallen Leaf", "Cascade"]

var [first, ...rest] = lakes

// var [first, ...rest, last] = lakes //안된다.

console.log(rest.join(", "))

 

5. 배열과 스프레드 연산자를 사용한 direction 함수 예시

 

세 점(...) 구문을 사용해 함수의 인자를 배열로 모을 수도 있다.

이런 식으로 함수 파라미터 정의에서 스프레드 연산자가 쓰일 때는 레스트 파라미터(rest parameters)라고 부른다.

 

아래에서는 n개의 인자를 스프레드 연산자를 사용해 배열로 모은 다음, 그 배열을 사용해 여러 가지 내용을 콘솔 메세지로 찍는 함수를 보여준다.

 

첫번째 목적지와 마지막 목적지를 출력하고, 그 사이에 있는 중간값들도 출력하는 것이다.

function d(...a) {
    let [sta, ...r] = a;
    let [f, ...sto] = r.reverse();

    console.log(`${a.length} 도시를 운행합니다.`); // 6 도시를 운행합니다.
    console.log(`${sta}에서 출발합니다.`); // 서울에서 출발합니다.
    console.log(`목적지는 ${f}입니다.`); // 목적지는 부산입니다.
    console.log(`중간에 ${sto.length} 군데를 들립니다.`); // 중간에 4 군데를 들립니다.
}

d (
    "서울",
    "수원",
    "천안",
    "대전",
    "대구",
    "부산"
);

 

1. (directions) 함수는 스프레드 연산자를 사용해 인자를 받는다.

2. 첫 번째 인자는 sta(start) 변수에 대입된다.

3. 마지막 인자는 f(finish) 변수에 Array.reverse를 통해 대입된다.

4. 그 후 a(args) 배열의 length를 사용해서 얼마나 많은 도시를 지나는지 보여준다. 목적지에 가는 동안 들러야 하는 도시의 수는 args 배열에서 2(출발지와 도착지)를 뺀 것이다. d(directions) 함수에 임의의 경유 도시 개수를 넘길 수 있기 때문에 이런 기능은 매우 편리하다.

// Convert arguments to an array with the spread operator
//    pick an array apart with spreads

function directions(...args) {
  var [start, ...remaining] = args
  var [finish, ...stops] = remaining.reverse()
  
  console.log(`drive through ${args.length} towns`)
  console.log(`start in ${start}`)
  console.log(`the destination is ${finish}`)
  console.log(`stopping ${stops.length} times in between`)
}

directions("Truckee", "Tahoe City", "Sunnyside", "Homewood", "Tahoma")

 

 

 

6. 객체 선언에 스프레드 연산자 사용하기

객체를 선언할 때 스프레드 연산자도 사용할 수 있다. 이 방법은 배열에 스프레드 연산자를 사용하는 방법과 비슷하다.아래를 보면 p에 ...m과 d를 넣은 걸 볼 수 있다.

const m = {
    b: "미역국",
    l: "삼치구이와 보리밥"
};

const d = "스테이크 정식";

const p = {
    ...m,
    d
};

console.log(p); // { b: '미역국', l: '삼치구이와 보리밥', d: '스테이크 정식' }

 

// Spread operator works with objects too

var morning = {
  breakfast: "oatmeal",
  lunch: "peanut butter and jelly"
}

var dinner = "mac and cheese"

var backpackingMeals = {
  ...morning,
  dinner
}

console.log(backpackingMeals)

 

 

참고자료

러닝 리액트(Learning React), 알렉스 뱅크스, 한빛미디어 (2021)

728x90
반응형