[모던 JavaScript 튜토리얼] 29. 구조 분해 할당(destructuring)
구조 분해 할당은 ES6(ES2015)에서 추가된 문법이다. 구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여, 그 값을 개별 변수에 담게 해주는 표현식이다.
배열 분해하기
let arr = ["Bora", "Lee"];
let [firstName, surname] = arr;
console.log(firstName); // Bora
console.log(surname); // Lee
구조 분해 할당을 이용해, firstName
에는 arr[0]을, surname
에는 arr[1]을 할당했다.
let [a, b, c] = "abc";
let [one, two, three] = new Set([1, 2, 3]);
할당 연산자 우측엔 모든 이터러블이 올 수 있다.
let user = {};
[user.firstName, user.surname] = "Bora Lee".split(" ");
console.log(user.firstName); // Bora
할당 연산자 좌측엔 할당할 수 있는 어떠한 것이든 올 수 있다.
let user = {
name: "John",
age: 30,
};
for (let [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`); // name: John, age: 30
}
Object.entries(obj)
에 구조 분해를 적용하면, 위와 같이 변수에 키, 값을 할당할 수 있다.
let a = 1,
b = 2,
c = 3;
[a, b, c] = [c, a, b];
console.log(a, b, c); // 3, 1, 2
구조 분해 할당을 사용하면, 별도의 변수 할당 없이 둘 혹은 그 이상의 변수의 값을 서로 바꿀 수 있다.
…로 나머지 요소 가져오기
let [name1, name2, ...rest] = [
"Julius",
"Caesar",
"Consul",
"of the Roman Republic",
];
console.log(name1); // Julius
console.log(name2); // Caesar
console.log(rest[0]); // Consul
console.log(rest[1]); // of the Roman Republic
console.log(rest.length); // 2
...
를 붙인 매개변수를 하나 추가하면 나머지(rest) 요소를 저장할 수 있다. rest
는 배열의 나머지 요소들이 모두 저장된 새로운 배열이다.
기본 값
let [firstName, surname] = [];
console.log(firstName, surname); // undefined undefined
위에서 볼 수 있듯이, 할당하고자 하는 변수의 개수가 분해하고자 하는 배열의 길이보다 크더라도 에러가 발생하지 않고 undefined
가 할당된다.
let [name = "Guest", surname = "Anonymous"] = ["Kim"];
console.log(name, surname); // Kim Anonymous
=
를 이용하면, 할당할 값이 존재하지 않을 때 기본 값을 설정할 수 있다.
let user = {
firstName: "Museong",
surname: "Kim",
};
let [firstName = getName(user), surname = getSurname(user)] = ["Museong"];
console.log(firstName, surname); // Museong Kim
function getFirstName(user) {
return user.firstName;
}
function getSurname(user) {
return user.surname;
}
위처럼 함수 호출문을 디폴트 값 할당문에 작성함으로써, 함수가 리턴하는 값을 기본 값으로 설정할 수도 있다.
객체 분해하기
let options = {
title: "Menu",
width: 100,
height: 200,
};
let { title, width, height } = options;
// let { height, title, width } = options;
console.log(title, width, height); // Menu 100 200
객체도 분해할 수 있다. 배열을 분해하는 방법과 동일하다. 변수 이름에 매칭되는 프로퍼티 값을 할당하므로, 위의 주석 처리된 부분을 실행해도 동일한 결과를 얻을 수 있다.
let options = {
title: "Menu",
width: 100,
height: 200,
};
let { width: w, height: h, title } = options;
console.log(title, w, h); // Menu 100 200
혹은 { 객체 프로퍼티 명: 타겟 변수 명 }
의 방식으로, :
뒤에 타겟 변수 명을 지정해줄 수 있다.
let options = {
title: "Menu",
};
let { width = 100, height = 200, title } = options;
console.log(title, width, height); // Menu 100 200
프로퍼티가 존재하지 않는 경우를 대비해, =
을 사용해 디폴트 값을 설정해줄 수 있다. 또한, 콜론(:
)과 할당 연산자(=
)를 동시에 사용할 수도 있다.
let options = {
title: "Menu",
width: 100,
height: 200,
};
let { height } = options;
console.log(height); // 200
프로퍼티가 많은 경우, 객체에서 원하는 정보만 뽑아올 수도 있다.
…로 나머지 요소 가져오기
let options = {
title: "Menu",
width: 100,
height: 200,
};
let { title, ...rest } = options;
console.log(title); // Menu
console.log(rest); // { width: 100, height: 200 }
배열과 마찬가지로 나머지 개념을 사용할 수 있다. rest
는 하나의 객체로써, 나머지 프로퍼티들이 담겨 새로운 객체를 이룬다.
중첩 구조 분해
let options = {
size: {
width: 100,
height: 200,
},
items: ["Cake", "Donut"],
extra: true,
};
let {
size: { width, height },
items: [item1, item2],
title = "Menu",
} = options;
console.log(width, height, item1, item2, title); // 100 200 Cake Donut Menu
배열이나 객체가 다른 배열이나 객체를 포함하는 복잡한 구조의 경우에도 정보를 추출할 수 있다. 이 과정을 중첩 구조 분해(nested destructuring)라고 한다. 구조 분해를 하는 과정에서, size
와 items
같이 실제 객체 내부의 프로퍼티 명에 해당하는 값은 가지지 않는 점을 유의하자.
똑똑한 함수 매개변수
function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
console.log(`${title} ${width} ${height}`); // My Menu 200 100
console.log(items); // [ 'Item1', 'Item2' ]
}
showMenu("My Menu", undefined, undefined, ["Item1", "Item2"]);
위처럼 매개변수의 디폴트 값을 사용하기 위해서는 그 인자로 undefined를 전달해야 한다. 그렇지 않으면, 정해진 파라미터의 순서를 어겨, 잘못된 곳에 값을 할당하게 된다. 위 경우보다 파라미터의 개수가 더 많다면, 선택적으로 매개변수를 전달하는 위의 방법은 지저분한 코드로 보일 것이다.
let options = {
title: "My Menu",
items: ["Item1", "Item2"],
};
function showMenu({
title = "Untitled",
width = 200,
height = 100,
items = [],
}) {
console.log(`${title} ${width} ${height}`); // My Menu 200 100
console.log(items); // [ 'Item1', 'Item2' ]
}
showMenu(options);
위처럼 전달할 매개변수들을 하나의 객체에 모아 객체 자체를 전달하면, 알아서 구조 분해해 올바른 이름의 매개변수에 할당한다.
댓글남기기