Language/JavaScript

[모던 JavaScript] 5.10 구조 분해 할당

뚜sh뚜sh 2023. 2. 7. 13:24

구조 분해 할당(destructuring assignment)

- 객체나 배열을 변수로 '분해'할 수 있게 해주는 특별한 문법

- 구조 분해 할당이란 명칭은 어떤 것을 복사한 이후에 변수로 '분해(destructurize)' 해준다는 의미 때문에 붙여짐

- 이 과정에서 분해 대상은 수정 또는 파괴되지 않으며, 배열의 요소를 직접 변수에 할당하는 것보다 코드 양이 줄어든다는 점만 다름

- 배열뿐만 아니라 모든 이터러블에 구조 분해 할당을 적용할 수 있음

- 두 변수에 저장된 값을 교환할 때 구조 분해 할당을 사용할 수 있음

 

 

 

배열 분해하기

// 이름과 성을 요소로 가진 배열
let arr = ["Bora", "Lee"]

// 구조 분해 할당을 이용해
// firstName엔 arr[0]을
// surname엔 arr[1]을 할당하였습니다.
let [firstName, surname] = arr;

alert(firstName); // Bora
alert(surname);  // Lee



// 아래 예시도 가능
let [firstName, surname] = "Bora Lee".split(' ');



// 쉼표를 사용하면 요소 무시 가능
// 두 번째 요소는 필요하지 않음
let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];

alert( title ); // Consul

 

 

 

'...'로 나머지 요소 가져오기

- 배열 앞쪽에 위치한 값 몇 개만 필요하고 그 이후 이어지는 나머지 값들은 한데 모아서 저장하고 싶을 때가 있음

- 이럴 때는 점 세 개 ... 를 붙인 매개변수 하나를 추가하면 '나머지' 요소를 가져올 수 있음

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

 

 

 

기본값

- 할당하고자 하는 변수의 개수가 분해하고자 하는 배열의 길이보다 크더라도 에러가 발생하지 않음

- 할당할 값이 없으면 undefined로 취급되기 때문

let [firstName, surname] = [];

alert(firstName); // undefined
alert(surname); // undefined

 

- '='을 이용하면 할당할 값이 없을 때 기본으로 할당해 줄 값인 '기본값'을 설정할 수 있음

// 기본값
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;

alert(title);  // Menu
alert(width);  // 100
alert(height); // 200


// let {...} 안의 순서가 바뀌어도 동일하게 동작함
let {height, width, title} = { title: "Menu", height: 200, width: 100 }

 

- 객체 프로퍼티를 프로퍼티 키와 다른 이름을 가진 변수에 저장하려면, 좌측 패턴에 콜론을 사용하면 됨

let options = {
  title: "Menu",
  width: 100,
  height: 200
};

// { 객체 프로퍼티: 목표 변수 }
let {width: w, height: h, title} = options;

// width -> w
// height -> h
// title -> title

alert(title);  // Menu
alert(w);      // 100
alert(h);      // 200

 

 

 

나머지 패턴 '...' (let 없이 사용하기)

- 아래처럼 코드를 작성하면 에러가 발생함

- 자바스크립트는 표현식 안에 있지 않으면서 주요 코드 흐름 상에 있는 {...}를 코드 블록으로 인식함

- 아래 예시도 구조 분해 할당을 위해 사용한 {...} 를 자바스크립트가 코드 블록으로 인식해서 에러가 발생함

let title, width, height;

// SyntaxError: Unexpected token '=' 이라는 에러가 아랫줄에서 발생합니다.
{title, width, height} = {title: "Menu", width: 200, height: 100};

 

- 에러를 해결하기 위해서 할당문을 괄호 (...) 로 감싸 자바스크립트가 {...}를 코드 블록이 아닌 표현식으로 해석하게 하면 됨

let title, width, height;

// 에러가 발생하지 않습니다.
({title, width, height} = {title: "Menu", width: 200, height: 100});

alert( title ); // Menu

 

 

 

중첩 구조 분해 (nested destructuring)

- 객체나 배열이 다른 객체나 배열을 포함하는 경우, 좀 더 복잡한 패턴을 사용하면 중첩 배열이나 객체의 정보를 추출할 수 있음

- 이것을 중첩 구조 분해라고 부름

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);