객체
와 배열
은 자바스크립트에서 가장 많이 쓰이는 자료 구조입니다.
개발을 하다 보면 함수에 객체나 배열을 전달해야 하는 경우가 생깁니다. 가끔은 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우가 생기기도 합니다.
이럴 때 객체나 배열을 변수로 '분해’할 수 있게 해주는 특별한 문법인 구조 분해 할당을 사용할 수 있습니다. 이 외에도 함수의 매개변수가 많거나 매개변수 기본값이 필요한 경우 등에서 구조 분해를 사용할 수 있습니다.
// 이름과 성을 요소로 가진 배열
let arr = ["HyeonJi", "Park"]
// 구조 분해 할당을 이용해
// firstName엔 arr[0]을
// surname엔 arr[1]을 할당
let [firstName, surname] = arr;
alert(firstName); // HyeonJi
alert(surname); // Park
이제 인덱스를 이용해 배열에 접근하지 않고도 변수로 이름과 성을 사용할 수 있습니다.
아래 예시처럼 split
같은 반환 값이 배열인 메서드를 함께 활용할 수도 있습니다.
let [firstName, surname] = "HyeonJi Park".split(' ');
배열 앞쪽에 위치한 값 몇 개만 필요하고 그 이후 이어지는 나머지 값들은 한데 모아서 저장하고 싶을 때가 있습니다. 이럴 때는 점 세 개 ...
를 붙인 매개변수 하나를 추가하면 ‘나머지(rest)’ 요소를 가져올 수 있습니다.
let [name1, name2, **...rest**] = ["Hyeonji", "Seohyun", "MyungJi", "SeongGyeong"];
alert(name1); // Hyeonji
alert(name2); // Seohyun
// `rest`는 배열입니다.
alert(rest[0]); // MyungJi
alert(rest[1]); // SeongGyeong
alert(rest.length); // 2*`
구조 분해 할당으로 객체도 분해할 수 있습니다. 기본 문법은 다음과 같습니다.
let {var1, var2} = {var1:…, var2:…}
할당 연산자 우측엔 분해하고자 하는 객체를, 좌측엔 상응하는 객체 프로퍼티의 '패턴’을 넣습니다.
let options = {
title: "WebPart",
width: 100,
height: 200
};
let {title, width, height} = options;
alert(title); // Menu
alert(width); // 100
alert(height); // 200
할당 연산자 좌측엔 좀 더 복잡한 패턴이 올 수도 있습니다. 분해하려는 객체의 프로퍼티와 변수의 연결을 원하는 대로 조정할 수도 있습니다.
let options = {
title: "WebPart",
width: 100,
height: 200
};
// { 객체 프로퍼티: 목표 변수 }
let {width: w, height: h, title} = options;
// width -> w
// height -> h
// title -> title
alert(title); // WebPart
alert(w); // 100
alert(h); // 200
프로퍼티가 없는 경우를 대비하여 =
을 사용해 기본값을 설정하는 것도 가능합니다.
let options = {
title: "WebPart"
};
let {**width = 100, height = 200**, title} = options;
alert(title); // WebPart
alert(width); // 100
alert(height); // 200
분해하려는 객체의 프로퍼티 개수가 할당하려는 변수의 개수보다 많다면 '나머지 패턴’을 사용할 수 있습니다.
나머지 패턴을 사용하면 배열에서 했던 것처럼 나머지 프로퍼티를 어딘가에 할당하는 게 가능합니다. 하지만 IE를 비롯한 몇몇 구식 브라우저는 나머지 패턴을 지원하지 않으므로 주의해서 사용해야 합니다. → 바벨(Babel)을 이용하면 됨
let options = {
title: "WebPart",
height: 200,
width: 100
};
// title = 이름이 title인 프로퍼티
// rest = 나머지 프로퍼티들
let {title, ...rest} = options;
// title엔 "WebPart", rest엔 {height: 200, width: 100}이 할당됩니다.
alert(rest.height); // 200
alert(rest.width); // 100
객체나 배열이 다른 객체나 배열을 포함하는 경우, 좀 더 복잡한 패턴을 사용하면 중첩 배열이나 객체의 정보를 추출할 수 있습니다. 이를 중첩 구조 분해라고 부릅니다.
let options = {
size: {
width: 100,
height: 200
},
items: ["EunBean", "AReum"],
extra: true
};
// 코드를 여러 줄에 걸쳐 작성해 의도하는 바를 명확히 드러냄
let {
size: { // size는 여기,
width,
height
},
items: [item1, item2], // items는 여기에 할당함
title = "WebPart" // 분해하려는 객체에 title 프로퍼티가 없으므로 기본값을 사용함
} = options;
alert(title); // WebPart
alert(width); // 100
alert(height); // 200
alert(item1); // EunBean
alert(item2); // AReum
위 예시에서 객체 options
의 size
프로퍼티 값은 또 다른 객체입니다. items
프로퍼티는 배열을 값으로 가지고 있습니다. 대입 연산자 좌측의 패턴은 정보를 추출하려는 객체 options
와 같은 구조를 갖추고 있습니다.
함수에 매개변수가 많은데 이중 상당수는 선택적으로 쓰이는 경우가 종종 있습니다.
function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
// ...
}
이렇게 함수를 작성하면 넘겨주는 인수의 순서가 틀려 문제가 발생할 수 있습니다. 이 외에도 대부분의 매개변수에 기본값이 설정되어 있어 굳이 인수를 넘겨주지 않아도 되는 경우에 문제가 발생합니다.
구조 분해는 이럴 때 사용할 수 있습니다.
매개변수 모두를 객체에 모아 함수에 전달해, 함수가 전달받은 객체를 분해하여 변수에 할당하고 원하는 작업을 수행할 수 있도록 함수를 리팩토링하면 다음과 같습니다.
// 함수에 전달할 객체
let options = {
title: "Web Part",
items: ["Item1", "Item2"]
};
// 함수는 전달받은 객체를 분해해 변수에 즉시 할당함
function showWebPart({
title = "Untitled",
width: w = 100, // width는 w에,
height: h = 200, // height는 h에,
items: [item1, item2] // items의 첫 번째 요소는 item1에, 두 번째 요소는 item2에 할당함
}) {
alert( `${title} ${w} ${h}` ); // My Menu 100 200
alert( item1 ); // Item1
alert( item2 ); // Item2
}
showWebPart(options);
객체 분해에 대해 깔끔하게 정리해주셔서 많은 도움이 되었습니다!! 감사해요 :)