[JavaScript] 구조분해할당, 중첩 구조분해

현지렁이·2023년 4월 23일
0
post-custom-banner

구조 분해 할당

객체와 배열은 자바스크립트에서 가장 많이 쓰이는 자료 구조입니다.

개발을 하다 보면 함수에 객체나 배열을 전달해야 하는 경우가 생깁니다. 가끔은 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우가 생기기도 합니다.

이럴 때 객체나 배열을 변수로 '분해’할 수 있게 해주는 특별한 문법인 구조 분해 할당을 사용할 수 있습니다. 이 외에도 함수의 매개변수가 많거나 매개변수 기본값이 필요한 경우 등에서 구조 분해를 사용할 수 있습니다.

배열 분해하기

// 이름과 성을 요소로 가진 배열
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);
post-custom-banner

1개의 댓글

객체 분해에 대해 깔끔하게 정리해주셔서 많은 도움이 되었습니다!! 감사해요 :)

답글 달기