유명한 담벼락

Javascript : Spread 구문과 Destructuring(구조 분해)

by 담담이담

1. Spread 구문

문자열, 객체, 배열을

바로 앞에 마침표 세 개를 붙임으로써 배열로 펼칠 수 있다.

 

 

cf)"..."을 붙이는 다른 문법

 

"..."을 붙이는 문법을 이전에 본 적이 있다.

바로 rest parameter를 이용할 때였는데,

 

rest parameter는 여러 개의 아규먼트를

하나의 파라미터로 묶는 방식이고,

 

spread 구문은 하나로 묶여있는 값을

개별 값으로 펼치는 방식이라는 차이가 있다.

 

 

i) spread 구문 사용 X 

 

const webPublishing = ['HTML', 'CSS'];
const interactiveWeb = webPublishing.slice();

interactiveWeb.push('JavaScript');

console.log(webPublishing);
console.log(interactiveWeb);

slice 메소드를 사용하지 않으면,

webPublishing 배열에도 push가 되어버리는 문제가 존재한다.

 

 

ii) spread 구문 사용 O

 

const webPublishing = ['HTML', 'CSS'];
const interactiveWeb = [...webPublishing, 'JavaScript'];

console.log(webPublishing);
console.log(interactiveWeb);

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

const arr3 = [...arr1, ...arr2];
console.log(arr3);

 

즉, Spread 구문은 splice 메소드를 사용하지 않고도 

배열이나 객체를 복사하거나

혹은 복사해서 새로운 요소들을 추가할 때 유용하게 활용될 수 있다.

 

 

 

배열을 펼쳐서 객체에 담으면 어떻게 될까?

인덱스가 프로퍼티 네임으로 만들어진 객체가 만들어진다.

참고로, 배열은 객체로 펼칠 수 있지만

객체는 배열로 펼칠 수 없다.

const members = ['태호', '종훈', '우재'];
const newObject = { ...members };

console.log(newObject); // {0: "태호", 1: "종훈", 2: "우재"}

const topic = {
  name: '모던 자바스크립트',
  language: 'JavaScript',
}
const newArray = [...topic]; // TypeError!

 

문자열을 펼쳐서 배열에 담을 수도 있다.

let my_string = "jaron";

console.log([...my_string]); //	[ 'j', 'a', 'r', 'o', 'n' ]

 

2. Destructuring (구조 분해)

배열과 객체와 같이 내부에 여러 값을 담고 있는 데이터 타입을 다룰 때

Destructuring 문법을 활용하면,

배열의 요소나 객체의 프로퍼티 값들을 개별적인 변수에 따로 따로 할당해서 다룰 수가 있다.

 

1) 배열의 구조 분해

// Array Destructuring
const members = ['코딩하는효준', '글쓰는유나', '편집하는민환', '책읽는담이'];
const [macbook, ipad, coupon] = members;

console.log(macbook); // 코딩하는효준
console.log(ipad); // 글쓰는유나
console.log(coupon); // 편집하는민환

 

개념

배열의 구조분해는 선언된 변수들에 배열의 인덱스의 순서에 따라 값이 할당된다.
즉,
배열의 형태를 한 변수 이름들([macbook, ipad, coupon])에

배열(rank)의 요소들이 순서대로 할당된다.

 

 

위처럼 선언된 변수의 개수와 배열의 길이가 같을 필요는 없다.

i) 할당하는 배열의 길이가 더 길 때,

인덱스에 따라 순서대로 할당되기에

길이가 넘치는 배열의 요소는 어디에도 할당되지 않는다.

 

ii) 할당하는 배열의 길이가 더 짧을때,

// Array Destructuring
const members = ['코딩하는효준', '글쓰는유나'];
const [macbook, ipad, coupon] = members;

console.log(macbook); // 코딩하는효준
console.log(ipad); // 글쓰는유나
console.log(coupon); // undefined

 

 

변수에 할당된 값을 교환할 때 사용되는 배열의 Destructuring

let macbook = '효준';
let ipad = '유나';

console.log("MAC 당첨자: ", macbook); // MAC 당첨자: 효준
console.log("iPad 당첨자: ", ipad); // ipad 당첨자 : 유나

[macbook, ipad] = [ipad, macbook];

console.log("MAC 당첨자: ", macbook); // MAC 당첨자: 유나
console.log("iPad 당첨자: ", ipad); // ipad 당첨자 : 효준

Destructuring을 사용하면 temp 변수를 사용하지 않고도 

값을 교환할 수 있다.

 

 

 

 

2) 객체의 구조 분해

 

// Object Destructuring
const macbookPro = {
  title: '맥북 프로 16형',
  price: 3690000,
  RAM : 32GB,
};

const { title, price, SSD} = macbookPro;

console.log(title); // 맥북 프로 16형
console.log(price); // 3690000
console.log(SSD) // undefined

개념

객체의 프로퍼티 하나하나에 접근할 때, 

점 표기법으로 접근하는 것이 아니라

간결하게 프로퍼티 네임 자체를 변수처럼 사용해서

접근하고자 할 때 사용한다.

 

 인덱스 순서대로 할당했던 배열의 구조분해와 다르게,

객체는 프로퍼티 네임을 통해 할당된다.

 

즉, 할당 연산자 왼편에 선언된 변수의 이름과

똑같은 프로퍼티 네임이 오른편 객체에 존재한다면,

그 변수에 그 프로퍼티 네임에 해당하는 값이 할당된다.

 

객체에 존재하지 않는 프로퍼티 네임의 변수가 존재한다면,

undefined가 할당되며,

할당 연산자를 통해 기본값을 지정해줄 수 있다.

 

 

그렇다면 변수 이름은 항상 프로퍼티 네임과 같아야할까? 

NO!

 

만약 title이라는 프로퍼티를 title 변수가 아닌, 

product에 할당받고 싶다면 

원래 프로퍼티 네임 : 원하는 변수 이름 형식으로 나타내면 된다.

 

// Object Destructuring
const macbookPro = {
  title: '맥북 프로 16형',
  price: 3690000,
  RAM : 32GB,
};

const {title : product} = macbookPro;

console.log(product); // 맥북 프로 16형

 

 

3) 함수의 구조 분해

 

i) 함수의 파라미터에서 배열의 구조 분해를 사용하는 경우

function printWinners([macbook, ipad, airpods, ...coupon]) {
  console.log('이벤트 결과를 알려드립니다!');
  console.log(`맥북의 주인공은 ${macbook}님 입니다.`);
  console.log(`아이패드의 주인공은 ${ipad}님 입니다.`);
  console.log(`에어팟 주인공은 ${airpods}님 입니다.`);
  console.log('코드잇 3개월 수강권 주인공은:');
  
  for (let user of coupon) {
    console.log(`- ${user}`);
  }
  
  console.log(`이상 총 ${coupon.length}명 입니다.`);
}

const ranks = ['효준', '효신', '재훈', '소원', '현승', '종훈']; // 배열 내부 문자열을 따옴표로 감싸줍니다.
printWinners(ranks);

 

ii) 함수의 파라미터에서 객체의 구조 분해를 사용하는 경우

 

const macbook = {
  title: '맥북 프로 16형',
  price: 3690000,
  color: 'silver',
  memory: '16GB',
  storage: '1TB SSD 저장 장치',
  display: '16형 Retina 디스플레이',
};

function printSummary({ title, color, price }) {
  console.log(`선택한 상품은 '${title}' 입니다.`);
  console.log(`색상은 '${color}'이며,`);
  console.log(`가격은 ${price}원 입니다.`);
}

printSummary(macbook);

 

 

const btn = document.querySelector('#btn');
btn.addEventListener('click', (event) => {
  event.target.classList.toggle('checked');
});

 

이벤트 핸들러를 사용할 때 

파라미터로 이벤트 객체가 전달되는데,

만약 매번 이벤트 객체에 접근하지 않고 

target 프로퍼티에만 접근한다면,

 

const btn = document.querySelector('#btn');
btn.addEventListener('click', ({target}) => {
  target.classList.toggle('checked');
});

파라미터에서 객체의 구조분해를 사용해서

이렇게 더 간단하게 나타낼 수 있다.

 

 

또한 classList도 객체이기 때문에 

중첩된 객체는 ":" 기호로 한 번 더 분해를 할 수도 있다.

이를 중첩 객체 구조 분해라고 한다.

const btn = document.querySelector('#btn');
btn.addEventListener('click', ({target : {classList}) => {
  classList.toggle('checked');
});

 

또는 중첩 객체 구조 분해를 하지 않아도,

함수 내부에서 한 번 더 구조분해를 할 수도 있다.

 

const btn = document.querySelector('#btn');
btn.addEventListener('click', ({target}) => {
  const {classList} = target;
  classList.toggle('checked');
});

 

 

4) Destructuring에서의 기본값과 rest 문법

함수에서 default parater, rest parameter를 다루듯이

Destructuring 문법을 활용할 때도 기본값과 rest 문법을 활용할 수 있다.

 

 

// Array Destructuring
const members = ['코딩하는효준', '글쓰는유나', undefined, '편집하는민환', '촬영하는재하'];
const [macbook, ipad, airpod = '녹음하는규식', ...coupon] = members;

console.log(macbook); // 코딩하는효준
console.log(ipad); // 글쓰는유나
console.log(airpod); // 녹음하는규식
console.log(coupon); // (2) ["편집하는민환", "촬영하는재하"]

// Object Destructuring
const macbookPro = {
  title: '맥북 프로 16형',
  price: 3690000,
  memory: '16 GB 2667 MHz DDR4',
  storage: '1TB SSD 저장 장치',
};

const { title, price, color = 'silver', ...rest } = macbookPro;

console.log(title); // 맥북 프로 16형
console.log(price); // 3690000
console.log(color); // silver
console.log(rest); // {memory: "16 GB 2667 MHz DDR4", storage: "1TB SSD 저장 장치"}

블로그의 정보

유명한 담벼락

담담이담

활동하기