구조 분해(Destructuring)는 ES2015 이후에 객체와 배열을 분열하는 문법입니다.
배열 구조분해
배열은 인덱스 값으로 객체는 key값으로 구성되어 있는 차이점 때문에 배열과 객체에 각각 적용하는 방식이 다릅니다. 먼저 배열부터 살펴봅시다.
const person = ['Jenny','Tom','Yunji','Kevin','Brian'];
const leader = person[0];
const teamLeader = person[1];
const asstManager = person[2];
const teamMember = [person[3], person[4]];
console.log(leader); //Jenny
console.log(teamLeader); //Tom
console.log(asstManager); //Yunji
console.log(teamMember); // ['Kevin', 'Brian']
이렇게 값을 할당하려면 시간도 오래 걸리고 비효율적 이어 보이죠? 그럼 다음 코드를 살펴봅시다.
const person = ['Jenny','Tom','Yunji','Kevin','Brian'];
const [leader, teamLeader, asstManager,...teamMember] = person; //할당되는 값이 배열이 아니면 에러
console.log(leader); //Jenny
console.log(teamLeader); //Tom
console.log(asstManager); //Yunji
console.log(teamMember); // ['Kevin', 'Brian']
위 코드에서는 변수 명을 대괄호[] 안에 배열처럼 선언하고 배열자체를 할당했습니다. 왼쪽의 선언된 변수들의 값이 person 배열에 왼쪽부터 차례대로 할당됩니다. (마지막 변수는 함수의 나머지 파라미터처럼 할당되고 나머지 값을 배열형태로 할당합니다.) 그렇다면 만약 person의 값이 더 적어진다면 어떻게 될까요? 다음 코드를 살펴보겠습니다.
const person = ['Jenny','Tom'];
const [leader, teamLeader, asstManager,...teamMember] = person; //할당되는 값이 배열이 아니면 에러
console.log(leader); //Jenny
console.log(teamLeader); //Tom
console.log(asstManager); //undefined
console.log(teamMember); // []
위 코드와 같이 변수는 undefined 그리고 배열은 빈 대괄호[]를 반환합니다. 이렇게 undefined 값으로 반환되었을 때 문제가 발생할 수도 있는대요. 이런 경우에는 그 값의 초기값을 다음과 같이 할당해 주면 됩니다.
const person = ['Jenny','Tom'];
const [leader, teamLeader, asstManager = 'John',...teamMember] = person; //할당되는 값이 배열이 아니면 에러
console.log(leader); //Jenny
console.log(teamLeader); //Tom
console.log(asstManager); //John
console.log(teamMember); // []
이런 식으로 배열 안에 선언된 변수에 값을 할당해 줌으로써 아무것도 할당 되지 않았을 때에 John을 반환할 수 있습니다. 또한 배열 구조 분해는 이미 저장된 두 변수의 값을 교환할 때도 사용할 수 있습니다.
let leader = 'Jenny';
let teamLeader = 'Tom';
console.log(leader,teamLeader); // Jenny Tom
[teamLeader, leader] = [leader,teamLeader];
console.log(leader,teamLeader); // Tom Jenny
위 코드와 같이 leader 였던 Jenny가 Tom으로, teamLeader였던 Tom이 Jenny로 바뀐 것이 보입니다. 만약 let 대신 const를 쓰면 각 변수의 값을 바꾸는 것이기 때문에 TypeError가 뜨는 것도 알아두시면 좋습니다.
객체 구조 분해
인덱스로 분해되었던 배열과 다르게 객체는 프로퍼티 네임으로 값이 구분이 되기 때문에 할당된 객체의 프로퍼티 네임과 같은 이름의 변수로 {}를 구성해야지 구조 분해가 됩니다. 이런 선언 방식으로 인해 간결하게 프로퍼티 네임을 변수 자체로 사용하려고 할 때 주로 사용합니다.
const product = {
name: "사과",
price: 1000,
origin: "한국",
nutrition: {
calorie: 52,
carbohydrate: 14,
protein: 0.3,
fat: 0.2,
}};
const {name, price} = product;
console.log(name); //사과
console.log(price); //1000
중괄호{} 안에 name과 price같이 product의 같은 프로퍼티 네임으로 선언해서 값을 반환했습니다. 만약 프로퍼티 네임이 같지 않으면 어떻게 될까요?
const {name, color} = product;
console.log(name); //사과
console.log(color); //undefined
이런 식으로 undefined 값이 출력됩니다. 이것 또한 아래처럼 할당연산자로 변수의 값을 미리 정해줄 수 있습니다.
const {name,color = '빨간색'} = product;
console.log(name); //사과
console.log(color); //빨간색
또한 배열과 똑같이 마침표 3개(...)를 사용해서 남은 하나의 객체로 모아 할당시킬 수 있습니다.
const {name, ...rest} = product;
console.log(name); //사과
console.log(rest); //name을 뺀 product 객체
그렇다면 나머지 프로퍼티를 제외하고 변수의 이름은 항상 같아야 할까요? 변수명은 같아야하지만 변수명을 자신이 원하는 대로 바꿀 수도 있습니다.
const {name: title, ...rest} = product;
console.log(title); //사과
console.log(rest); //name을 뺀 product 객체
이렇게 콜론(:)기호를 이용해서 객체의 프로퍼티 네임을 선언하듯이 사용하면 가능합니다! 그리고 객체에는 변수이름으로 사용할 수 없는 경우가 있는대요 이럴 때도 위와 같이 이름만 정의해 준다면 변수로 사용할 수 있습니다.
const product = {
name: "사과",
price: 1000,
origin: "한국",
nutrition: {
calorie: 52,
carbohydrate: 14,
protein: 0.3,
fat: 0.2,
},
'id': '14321' //변수로 사용 불가
};
const {'id' : id} = product; //id로 이름정해주기
console.log(id); //14321
함수 파라미터로써의 활용
앞서서 배열과 객체의 구조 분해 문법을 알아봤는대요. 이를 응용해서 함수의 파라미터 변수를 구조분해의 선언하는 방식으로 값을 할당 받을 수 있습니다.
function printTeam([leader,teamLeader,asstManager, ...teamMember])// 파라미터 구조분해 {
console.log('Team Members');
console.log(`Leader is ${leader}`);
console.log(`Team leader is ${teamLeader}`);
console.log(`Assist Manager is ${asstManager}`);
for (let member of teamMember) {
console.log(`Team Member is ${member}`);
}
}
const team = ['Jenny','Tom','Yunji','Kevin','Brian'];
printTeam(team);
// Team Members
// Leader is Jenny
// Team leader is Tom
// Assist Manager is Yunji
// Team Member is Kevin
// Team Member is Brian
함수의 파라미터에 변수의 순서대로 배열로 선언해주었고 아규먼트 값으로 team이라는 배열을 전달했습니다. 이를 객체에서도 똑같이 이용할 수 있습니다.
const product = {
name: "사과",
price: 1000,
origin: "한국",
nutrition: {
calorie: 52,
carbohydrate: 14,
protein: 0.3,
fat: 0.2,
},
};
function printProduct({name, price, origin}) {
console.log(name);
console.log(price);
console.log(origin);
}
printProduct(product);
// 사과
// 1000
// 한국
마무리
구조 분해는 뒤에서 나오는 React Framework나 자바스크립트 기반 라이브러리에서 자주 사용되므로 잘 기억해두는게 좋습니다. 초보 개발자가 끄적이는 공부노트라 틀린 것이 있을 수 있습니다. 틀린 점 지적은 언제나 환영합니다!
Reference
Codeit 모던 자바스크립트 구조분해