반응형

구조 분해 할당

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

코드 작성을 하다 보면 함수에 객체나 배열을 전달하는 경우나, 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우도 생깁니다.

이럴 때 객체나 배열을 변수로 분해할 수 있게 해주는 문법이 구조 분해 할당( Destructuring Assignment )입니다.

이 외에도 함수의 매개변수가 많거나 매개변수 기본 값이 필요한 경우 등에서 구조 분해( Destructuring )는 진가를 발휘합니다.

 

배열 분해하기

이렇게 사용하면 인덱스를 이용해서 배열에 접근하지 않고 변수로 사용할 수 있게 됩니다.

const arr = ["Hello", "World"];

// 구조 분해 할당을 이용해서 각각에 Hello와 World를 할당합니다.
const [first, second] = arr;

console.log(first); // Hello
console.log(second); // World

 

split() 메서드와 함께 사용하기

const str = "Hello World";

const [first, second] = str.split(" ");

console.log(first); // Hello
console.log(second); // World

 

분해( Destructuring )의 의미

구조 분해 할당이란 명칭은 어떤 것을 복사한 이후 변수로 분해 해준다는 의미 때문에 붙었습니다. 이 과정에서 수정 혹은 파괴되지 않습니다.

 

쉼표를 사용해서 요소 버리기

쉼표를 사용하면 필요하지 않은 배열의 요소를 버릴 수 있습니다.

const arr = ["안녕", "하세요", "저는", "Shiro", "21입니다."];

const [first, , second, third] = arr;
console.log(first); // 안녕
console.log(second); // 저는
console.log(third); // Shiro

 

할당 연산자 우측엔 모든 iterable( 이터러블 )이 올 수 있습니다.

배열뿐 아니라 모든 iterable( 반복 가능한 객체 )에 구조 분해 할당을 적용할 수 있습니다.

const [a, b, c] = "abc";
const [one, two, three] = new Set([1, 2, 3]);
console.log(a); // a
console.log(b); // b
console.log(c); // c

console.log(one); // 1
console.log(two); // 2
console.log(three); // 3

 

할당 연산자 좌측에는 무엇이든 올 수 있습니다.

할당 연산자 좌측에는 할당할 수 있는( Assignables )것이라면 어떤 것이든 올 수 있습니다.

const str = "Jun Hyeok"
const user = {};
[user.Firstname, user.secondName] = str.split(" ");

console.log(user.Firstname); // Jun
console.log(user.secondName); // Hyeok

 

.entries() 메서드로 반복하기

entries() 메서드와 구조 분해를 조합하면 객체의 키와 값을 순회해서 변수로 분해 할당할 수 있습니다.

const user = {
  name: "Shiro",
  age: 31
};

for (let [key, value] of Object.entries(user)) {
  console.log(`key: ${key}, value: ${value}`); 
  /*
    key: name, value: Shiro
    key: age, value: 31
  */
}

 

변수 교환 트릭

두 변수에 저장된 값을 교환할 때 구조 분해 할당을 사용할 수 있습니다.

let Guest = "Shiro";
let Admin = "Jun";

[Guest, Admin] = [Admin, Guest];

console.log(`Guest: ${Guest}, Admin: ${Admin}`); // Guest: Jun, Admin: Shiro

 

이 방식을 사용하면 2개 이상의 변수에 담긴 값도 교환할 수 있습니다.

 

스프레드 연산자로 나머지 요소 가져오기

배열 앞쪽에 위치한 값 몇 개만 필요하고 그 이후 이어지는 나머지 값들은 한데 모아 저장하고 싶을 때 스프레드 연산자인 ...을 붙인 매개변수를 추가하면 나머지 요소를 가져올 수 있습니다.

let [first, second, ...third] = ["A", "B", "C", "D", "E", "F", "G", "H"];

console.log(first); // A
console.log(second); // B
console.log(third); // ['C', 'D', 'E', 'F', 'G', 'H']
console.log(third.length); // 6

...뒤에는 다른 이름이 와도 괜찮지만, 변수 앞에 ...과 가장 마지막에 위치해야 한다는 점은 지켜주어야 합니다.

 

기본 값

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

let [first, second] = [];

console.log(first); // undefined
console.log(second); // undefined

할당할 값이 없으면 undefined로 취급됩니다.

 

객체 분해하기

구조 분해 할당으로 객체도 분해할 수 있습니다.

let { cnt1, cnt2 } = { cnt1: "", cnt2: "" }
let options = {
  title: "New World",
  subTitle: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
  width: 1000,
  height: 1000
};

let {title, subTitle, width, height} = options;

console.log(title, subTitle, width, height); // New World ABCDEFGHIJKLMNOPQRSTUVWXYZ 1000 1000

순서는 중요하지 않습니다.

 

할당 연산자 좌측에 좀 더 복잡한 패턴이 올 수 있습니다. 분해하려는 객체의 프로퍼티와 변수의 연결을 원하는 대로 조정할 수 있습니다.

let options = {
  title: "New World",
  subTitle: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
  width: 1000,
  height: 1000
};

let {title: tt, subTitle, width: w, height: h} = options;

console.log(tt, w, h); // New World 1000 1000

 

프로퍼티가 없는 경우를 대비해서 =을 사용해서 기본 값을 설정하는 것도 가능합니다.

let options = {
  title: "New World",
  subTitle: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
  width: 1000,
  height: 1000
};

let {title, abc = 100} = options;

console.log(title, abc); // New World 100

 

나머지 패턴 ...

나머지 패턴( Rest Pattern )을 사용하면 배열에서 했던 것처럼 나머지 프로퍼티를 어딘가에 할당하는 것이 가능합니다.

let options = {
  title: "New World",
  subTitle: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
  width: 1000,
  height: 1000
};

let {subTitle, ...rest} = options;

console.log(subTitle, rest.title); // ABCDEFGHIJKLMNOPQRSTUVWXYZ New World

 

중첩 구조 분해

객체나 배열이 다른 객체나 배열을 포함하는 경우, 좀 더 복잡한 패턴을 사용하면 중첩 배열이나  객체의 정보를 추출할 수 있습니다. 이를 중첩 구조 분해( Nested Destructuring )라고 합니다.

let options = {
  size: {
    width: 1000,
    height: 1000
  },
  items: ["Hello", "World"],
  bool: true
};

let { size: { width, height }, items: [ item1, item2 ], title = "Main" } = options;

console.log(width); // 1000
console.log(height); // 1000
console.log(item1); // Hello
console.log(item2); // World
console.log(title); // Main

title은 프로퍼티가 없으므로 기본 값을 넣어주었습니다.

반응형

+ Recent posts