본문 바로가기
Programming/JavaScript

Javascript - 구조 분해 할당 (Destructuring assignment)

by Muko 2020. 4. 24.

구조 분해 할당 (Destructuring assignment)

Destructuring?

  • 구조화된 배열 또는 객체를 분해해서 개별적인 변수에 할당 하는 것.
  • 배열 또는 객체에서 필요한 값만 추출해서 변수에 할당하거나 반환할 때 유용하다.
  • ex) 함수의 매개변수가 많거나, 매개변수 기본값이 필요한 경우 등

 

Array Destructuring

const numbers = [1, 2, 3];
const [one, two, three] = numbers;
console.log(one, two, three);  // 1, 2, 3

const [one, two] = [1]; // 1, undefined

// 반환 값이 배열인 메서드와 사용가능
const [firstName, surname] = 'Giin Lee'.split(' '); // Giin, Lee

 

특징

  • 인덱스로 배열에 접근하지 않아도 변수로 각 요소에 접근하는 것이 가능하다.
  • 분해과정에서 분해 대상은 수정 또는 파괴되지 않는다.
  • 쉼표를 사용해서 필요하지 않은 배열 요소를 건너 뛸 수 있다.
  • 할당할 변수가 없을 경는 요소들은 생략된다.
const [one,  , three] = [1, 2, 3, 4]; // 1, undefined, 3

 

  • 배열 뿐만 아니라 iterable한 객체라면 구조 분해 할당 적용 가능하다.
const [a, b, c] = 'abc'; // ['a', 'b', 'c']

 

  • '...'를 이용해서 나머지 요소들을 한 번에 가져올 수 있다.
const [name1, name2, ...rest] = ['Julius', 'Caesar', 'Consul', 'of the Roman Republic'];
console.log(rest); // ['Consul', 'of the Roman Republic'];

 

 

  • 기본 값을 설정할 수 있다.
const [one, two = 20, three = 30] = [1, 2]; // 1, 2, 30

 

 

  • 할당 연산자 좌측에 할당할 수 있는 것은 모두 가능하다.
const user = {};
[user.name, user.surname] = 'Giin Lee'.split(' '); // Giin, Lee

 

 

  • Object.entries(obj)와 구조 분해를 조합하면 객체의 키와 값을 순회해 변수로 분해 할당 가능하다.
const user = {
  name: 'John',
  age: 30
};

// 객체의 키와 값 순회
for (let [key, value] of Object.entries(user)) {
  console.log('key:', key, 'value:', value);
}

 

 

  • 맵 요소도 순회 가능하다.
const user = new Map();
user.set("name", "Giin");
user.set("age", 27);

for (let [key, value] of user) {
  console.log('key:', key, 'value:', value);
}

 

Object Destructuring

const options = {
  title: 'Menu',
  width: 100,
  height: 200
};
const {title, width, height} = options;
console.log(title, width, height); // Menu, 100, 200

 

특징

  • 객체의 프로퍼티를 분해하는 것이기 대문에 순서는 중요하지 않다.
const {height, width, title} = {title: 'Menu', height: 200, width: 100};

 

 

  • 객체 프로퍼티를 프로퍼티 키와 다른 이름을 가진 변수에 저장 가능하다.
const options = {
  title: 'Menu',
  width: 100,
  height: 200
};
// { 객체 프로퍼티: 목표 변수 }
const {width: w, height: h, title} = options;

console.log(w, h, title); // 100, 200, Menu

 

 

  • 프로퍼티가 없을 때 default값을 설정 가능하다.
const {width=100, height=200, title} = options;

 

 

  • 배열과 객체 모두 함수 호출을 기본값으로 할당 가능하다.
const {width = prompt("width?"), title = prompt("title?")} = options;

 

 

  • 프로퍼티가 많은 객체에서 원하는 정보만 가져오는 것이 가능하다. 함수 파라미터가 많을 때 유용하다.
const options = {title: 'Menu', width: 100, height: 200};
const { title } = options;

 

 

  • 배열과 마찬가지로 객체도 나머지 패턴('...')이 가능하다. 일부 지원되지 않는 브라우저가 있으므로 바벨로 폴리필 해서 사용해야 한다.
const options = { title: 'Menu', height: 200, width: 100 };
const {title, ...rest} = options;
console.log(rest); // {height: 200, width: 100}

 

 

  • 기존에 있던 변수에도 구조 분해된 값을 할당할 수 있다. 이 때 자바스크립트가 표현식 안에 있지 않으면서 주요 코드 흐름 상에 있는 {...}를 코드 블록으로 인식하기 때문에 다음과 같이 괄호로 감싸서 사용해야 한다.
let title, width, height;
( {title, width, height} = {title: 'Menu', width: 200, height: 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;

console.log(title, width, height, item1, item2); // Menu 100 200 Cake Donut

 

함수 매개변수에서 사용하기

// 함수에 전달할 객체
let options = {
  title: "My menu",
  items: ["Item1", "Item2"]
};

// 전달받은 객체를 변수에 즉시 할당함
function showMenu({
  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
}

showMenu(options);

위와 같이 매개변수를 객체에 모아서 함수에 전달했을 때, 함수 내부에서 객체를 분해해서 변수에 할당하는 것이 쉬워진다. 다만 이렇게 구현할 경우 반드시 함수에 값이 전달된다는 가정이 존재하므로, 넣을 값이 없을 경우에는 빈 객체를 명시적으로 전달해야한다.

댓글1