구조분해 할당은 함수에 객체나 배열의 일부만 전달해야할 때 이를 변수로 분해할 수 있게 해주는 특별한 문법이다.
// 이름과 성을 요소로 가진 배열
let arr = ["Bora", "Lee"]
// 구조 분해 할당을 이용해
// firstName엔 arr[0]을
// surname엔 arr[1]을 할당하였습니다.
let [firstName, surname] = arr;
위와 같은 방법이 배열을 변수로 분해한 과정이다.
이렇게 구조분해할당을 하면 각 요소에 arr[0]
, arr[1]
처럼 인덱스로 접근하지 않고도 사용할 수 있다.
이 방법을 통해 각 배열의 요소를 변수에 할당하는 코드의 길이를 줄일 수 있다.
쉼표를 사용하면 특정 요소를 버리고 나머지 요소만 변수로 분해할 수 있다.
let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"]; alert( title ); // Consul
위와 같인 코드에서는 두번째 요소를 할당할 변수가 비어있기 때문에, Caesar는 버려지고 Julius와 Consul만 각각의 변수에 담기게 된다.
이런 구조분해할당은 모든 iterable에서 가능하다.
즉, 배열이 아닌 문자열도 구조 분해가 가능하다.
let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]);
또한 할당 연산자의 좌측에도 일반 변수로 구성된 배열 뿐만 아니라 할당 가능한 모든 것이 올 수 있다.
예를들어 아래와 같이 객체의 값에도 구조 분해 할당이 가능하다.
let user = {};
[user.name, user.surname] = "Bora Lee".split(' ');
alert(user.name); // Bora
.entries()
를 사용해서 key와 value를 한번에 입력하여 객체의 키와 값을 순회할 수 있다.
let user = {
name: "John",
age: 30
};
// 객체의 키와 값 순회하기
for (let [key, value] of Object.entries(user)) {
alert(`${key}:${value}`); // name:John, age:30이 차례대로 출력
}
두 변수에 저장된 값을 SWAP하고자 할 때 원래는 임시 변수를 만들어서 3번의 대입연산을 통해 SWAP 할 수 있었다.
하지만 구조 분해 할당을 사용하면 한줄로 매우 쉽게 SWAP이 가능하다.
let guest = "Jane";
let admin = "Pete";
// 변수 guest엔 Pete, 변수 admin엔 Jane이 저장되도록 값을 교환함
[guest, admin] = [admin, guest];
alert(`${guest} ${admin}`); // Pete Jane
구조 분해 할당은 모두 각각의 요소로 분해하는 것이 아니라, 일부는 요소로, 나머지는 하나의 배열로 묶어서 구조 분해 할당을 할 수도 있다.
그럴 땐, 추출하고 싶은 요소는 각각의 변수명을 붙여주고, 한데 묶을 나머지는 ...arr
를 통해 arr라는 하나의 배열로 묶어줄 수 있다.
let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
alert(name1); // Julius
alert(name2); // Caesar
// `rest`는 배열입니다.
alert(rest[0]); // Consul
alert(rest[1]); // of the Roman Republic
alert(rest.length); // 2
=
를 사용하자// 기본값
let [name = "Guest", surname = "Anonymous"] = ["Julius"];
alert(name); // Julius (배열에서 받아온 값)
alert(surname); // Anonymous (기본값)
let {var1, var2} = {var1:…, var2:…}
let options = {
title: "Menu",
width: 100,
height: 200
};
let {title, width, height} = options; // 이때 title,width,height의 순서는 상관없다
alert(title); // Menu
alert(width); // 100
alert(height); // 200
만약 키와 다른 이름을 가진 변수에 저장하고 싶다면, 다음과 같은 형태를 사용한다.
let {키 명1: 원하는 변수명1, 키 명2: 원하는 변수명2, 키 명3} = 객체;
let options = {
title: "Menu"
};
let {width = 100, height = 200, title} = options;
alert(title); // Menu
alert(width); // 100
alert(height); // 200
...
를 사용하여 나머지 프로퍼티를 묶는 것이 가능하다. let options = {
title: "Menu",
height: 200,
width: 100
};
// title = 이름이 title인 프로퍼티
// rest = 나머지 프로퍼티들
let {title, ...rest} = options;
// title엔 "Menu", rest엔 {height: 200, width: 100}이 할당됩니다.
alert(rest.height); // 200
alert(rest.width); // 100
let options = {
size: {
width: 100,
height: 200
},
items: ["Cake", "Donut"],
extra: true
};
// 코드를 여러 줄에 걸쳐 작성해 의도하는 바를 명확히 드러냄
let {
size: { // size는 여기,
width,
height
},
items: [item1, item2], // items는 여기에 할당함
title = "Menu" // 분해하려는 객체에 title 프로퍼티가 없으므로 기본값을 사용함
} = options;
alert(title); // Menu
alert(width); // 100
alert(height); // 200
alert(item1); // Cake
alert(item2); // Donut
// 함수에 전달할 객체
let options = {
title: "My menu",
items: ["Item1", "Item2"]
};
// 똑똑한 함수는 전달받은 객체를 분해해 변수에 즉시 할당함
function showMenu({title = "Untitled", width = 200, height = 100, items = []}) {
// title, items – 객체 options에서 가져옴
// width, height – 기본값
alert( `${title} ${width} ${height}` ); // My Menu 200 100
alert( items ); // Item1, Item2
}
showMenu(options);