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 저장 장치"}
'Javascript' 카테고리의 다른 글
Javascript : MAP과 SET 자료형 (0) | 2023.10.03 |
---|---|
Javascript : 배열의 요소를 하나씩 살펴보며 반복 작업을 하는 메소드 (0) | 2023.10.03 |
Javascript : 객체의 프로퍼티 접근 방식과 모던한 프로퍼티 표기법 (0) | 2023.10.01 |
Javascript : null 병합 연산자, 조건부 연산자, 옵셔널 체이닝 (1) | 2023.10.01 |
Javascript : JS에서의 함수 (1) | 2023.10.01 |
블로그의 정보
유명한 담벼락
담담이담