객체와 배열은 JavaScript에서 가장 많이 쓰이는 자료 구조입니다.
키를 가진 데이터 여러 개를 저장할 때는 객체를,
데이터를 순서대로 저장할 때는 배열을 사용합니다.
상황에 따라 객체나 배열의 저장된 데이터 전체가 아닌 일부만 필요한 경우가 생깁니다. 이때 객체나 배열을 분해할 수 있게 도와주는 문법이 구조 분해 할당 (Destructuring assignment)입니다. 함수의 매개변수가 많거나 매개변수 기본값이 필요한 경우 구조분해가 진가를 발휘합니다.
let arr = ["KJ", "SJ"]
let [firstName, secondName] = arr;
console.log(firstName); // KJ 출력
console.log(secondName); // SJ 출력
구조 부해 할당은 복사한 후 변수로 분해 해주는 것입니다. 분해 대상을 수정하거나 파괴하지 않습니다.
쉼표를 사용할 경우 요소를 무시하고 그 다음 요소로 넘어갑니다. (생략이라고 생각하면 됩니다.)
let [firstName, , title] = ["KJ", "SJ", "SH", "KO"];
console.log(title); // SH를 출력합니다. 두 번 째 값 SJ를 생략하고 넘어갑니다.
iterable에 구조 분해 할당을 적용할 수 있습니다.
let[a, b, c] = "abc"; // ["a", "b", "c"]
let[one, two, three] = new Set([1, 2, 3]);
let user = {};
[user.name, user.lastName] = "KJ Lee".split(' ');
console.log(user.name); // KJ 출력
키와 값을 순회해 변수로 분해 후 할당할 수 있습니다.
let user = {
name: "KJ",
age: 31
};
for(let [key, value] of Object.entries(user)){
console.log(`${key}: ${value}`);
} // name: KJ, age: 31 이 출력됩니다.
배열 앞쪽에 필요한 요소를 제외 후 나머지 값을 한 곳에 모아 저장하고 싶을 때 ...을 사용하면 됩니다. ...을 붙인 매개변수에 나머지 요소를 저장할 수 있습니다.
let [name1, name2, ...rest] = ["KJ', "SJ", "SH", "KO", "NO"];
console.log(name1); // KJ 출력
console.log(name2); // SJ 출력
// 여기 밑에서부터는 ...rest 영역이기에 잘 봐야한다.
console.log(rest[0]); // SH 출력
console.log(rest[1]); // KO 출력
console.log(rest.length); // 3 출력
...rest에는 나머지 배열 요소들이 저장된 새로운 배열을 만듭니다. (당연히 rest 대신 사용해도 됩니다.) 하지만 ...은 가장 마지막 변수에 사용해야 합니다.
let [firstName, secondName] = [];
console.log(firstName); // undefined;
console.log(secondName); // undefined;
구조 분해 할당을 통해 객체도 분해할 수 있습니다.
ex) 객체 키 목록을 태펀으로 사용하는 문법
let options = {
title: "Menu",
width: 100,
height: 300
};
let{title, width, height} = options;
console.log(title); // Menu 출력
console.log(width); // 100 출력
console.log(height); // 300 출력
객체에서는 순서가 중요하지 않습니다. 상응하는 변수에 따라 동작합니다.
let options = {
title: "Menu",
width: 100,
height: 300
};
let{width: w, height: h, title} = options;
console.log(title); // Menu 출력
console.log(w); // 100 출력
console.log(h); // 300 출력
:(콜론) 대시 =(할당 연산자)를 사용할 수 있습니다.
let options = {
title: "Menu",
width: 100,
height: 300
};
let{title, ...rest} = options;
console.log(title); // Menu 출력
console.log(rest.width); // 100 출력
console.log(rest.height); // 300 출력
ex) 잘못된 예
let title, width, height;
{title, width, height} = {title: "Menu", width: 200, height: 100};
{...} 을 하나의 블록으로 인식해 활용할 수 없습니다.
따라서 {} = {} 사용하고 싶을 때 () 묶어줘야 합니다.
ex) 잘 사용된 예
let title, width, height;
({title, width, height} = {title: "Menu", width: 200, height: 100});
console.log(title); // Menu 출력
객체나 배열이 다른 객체나 배열을 포함하는 경우, 복잡한 패턴을 사용하면 중첩 배열이나 객체의 정보를 추출할 수 있습니다. 이를 중첩 구조 분해(nested destructuring)라고 부릅니다.
분해하려는 객체에 프로퍼티가 없으면 기본값을 사용합니다. (기본값은 별도로 설정합니다.)
함수에 매개변수가 많은데 상당수는 선택적으로 사용하는 경우가 많습니다.
ex) 리팩토리 전 함수
function showMenu(title = "Untitled", width = 200, height = 100, items = []){
//
}
함수 작성 때는 넘겨주는 인수의 순서가 틀리면 문제가 발생할 수 있습니다.
하지만 구조 분해에서는 매개변수 모두를 모아 함수에 전달합니다. 전달받은 객체를 분해하여 변수에 할당하고 원하는 작업을 수행할 수 있습니다.
ex) 함수에 전달할 객체와 전달받은 객체를 분해해 변수에 할당한 예
let options = {
title: "My menu",
items: ["Item1", "Item2"]
};
function showMenu({title = "Untitled", width = 200, height = 100, items = []}){
console.log(`${title} ${width} ${height}`);
console.log(items);
}
showMenu(options);
// My menu 200 100 출력
// Item1, Item2 출력
width: h = 100 과 같은 콜론을 사용해서 복잡한 구조를 단순화 할 수 있습니다.
let options = {
title: "My menu",
items: ["Item1", "Item2"]
};
function showMenu({
title = "Untitled",
width: w = 100,
height: h = 200, ,
items: [item1, item2]
}) {
alert( `${title} ${w} ${h}` );
alert( item1 ); // Item1
alert( item2 ); // Item2
}
showMenu(options);
// My menu, 100, 200 출력
// Item1 출력
// Item2 출력
구조 분해 할당을 사용하면 객체나 배열을 변수로 연결할 수 있습니다.
무슨 말인지 하나도 모르겠으니까.. 나중에 다시 보자.