JavaScript/JavaScript 문법

[ECMAScript]구조 분해(destructuring)

DevStory 2021. 5. 29.

구조 분해(destructuring)는 객체와 배열 안에 있는 값을 추출하여 변수에 대입하는 편리한 방법입니다.

 

객체의 속성을 추출하여 변수에 대입하는 기존의 방식

var person = {
  name: 'Kang JaeSeong',
  age: 29
};

var name = person.name;
var age = person.age;

console.log(`name : ${name} / age : ${age}`); // "name : Kang JaeSeong / age : 29"

person.name의 값이 name변수에 할당되었습니다. 동일한 방식으로 persone.age의 값이 age 변수에 할당되었습니다. 만약, person 객체의 속성이 10개일 경우 10개의 변수에 값을 할당해야 합니다.

 

이러한 방식은 구조 분해를 사용하면, 코드 한 줄로 처리가 가능합니다.

var person = {
  name: 'Kang JaeSeong',
  age: 29
};

var { name, age, address } = person;

console.log(`name : ${name} / age : ${age} / address : ${address}`);
// "name : Kang JaeSeong / age : 29 / address : undefined"

위 코드는 변수 name, age, address를 선언하고 person 객체의 필드와 같은 이름일 경우 persone 객체의 필드 값을 대입합니다. 변수 address는 person 객체에 address 필드가 없으므로 undefined로 설정됩니다.

 

정리하자면, 기존 방식인 좌측의 코드는 구조 분해를 사용하여 코드 한 줄로 처리가 되었습니다.

 

배열도 구조 분해가 가능합니다.

var numbers = [1, 2, 3, 4, 5];
var [one, two, three, four] = numbers; 
// var [one, two, three, four] = [1, 2, 3, 4, 5];와 동일합니다.

console.log(`one : ${one}`); // "one : 1"
console.log(`two : ${two}`); // "two : 2"
console.log(`three : ${three}`); // "three : 3
console.log(`four : ${four}`); // "four : 4"

배열은 인덱스 순서대로 구조 분해가 되어 변수에 대입됩니다.

 

무시하고 싶은 요소는 리스트 매칭(list matching)을 사용합니다. 무시하고 싶은 위치에 콤마 , 를 사용합니다.

var numbers = [1, 2, 3, 4, 5];
var [, , , , five] = numbers; 

console.log(`five : ${five}`); // "five : 5"

객체의 경우에는 구조 분해 시 중괄호 {}를 사용해야 하며, 배열의 경우에는 대괄호 []를 사용해야 합니다.

아래와 같이 사용할 경우 에러가 발생합니다.

var person = {
  name: 'Kang JaeSeong',
  age: 29
};
var [ name, age, address] = person;

var numbers = [1, 2, 3, 4, 5];
var {one, two, three, four} = numbers;

기본값 설정

구조 분해된 객체에 존재하지 않는 속성을 접근할 경우 undefined로 설정이 됩니다. 객체에 속성이 존재하지 않는 경우 기본값 설정이 가능합니다.

var person = {
  name: 'Kang JaeSeong',
  age: 29
};

var { name , age, address = 'Busan'} = person;

console.log(`name : ${name} / age : ${age} / address : ${address}`);
// "name : Kang JaeSeong / age : 29 / address : Busan"

배열도 기본값 설정이 가능합니다.

var numbers = [1, 2, 3];
var [one, two, three, four = 4] = numbers;

console.log(`one : ${one}`); // "one : 1"
console.log(`two : ${two}`); // "two : 2"
console.log(`three : ${three}`); // "three : 3"
console.log(`four : ${four}`); // "four : 4"

numbers라는 배열에는 3개의 요소만 존재하기 때문에 four이라는 변수는 기본값으로 설정되었습니다.

 


별칭(Alias)

배열은 상관없지만, 객체의 경우에는 변수의 이름과 속성의 명칭이 동일할 경우 변수에 값이 설정되었습니다. 변수의 이름을 다르게 작성하고 싶을 경우 별칭(Alias)을 사용합니다.

 

기본 값으로 설정된 변수도 별칭을 사용할 수 있습니다.

var person = {
  name: 'Kang JaeSeong',
  age: 29
};

var { name : name001, age : age001, address : address001 = 'Busan'} = person;
  
console.log(name001); // "Kang JaeSeong"
console.log(age001);  // 29
console.log(address001); // "Busan"

중첩된 객체의 구조 분해

위 예제는 단순했으나 종종 JavsScript에서 객체가 중첩되어 사용되는 경우가 있습니다. 중첩된 객체를 구조 분해하는 경우 중첩된 중괄호 {}로 속성에 접근합니다.

var person = {
  nameProperty: {
    firstName : 'Kang',
    middleName :'Jae',
    lastName : 'Seong'
},
  age: 29
};

var { nameProperty : {firstName}} = person;
  
console.log(firstName); // "Kang"

위의 구문은 아래와 같습니다.

만약, 위 코드보다 복잡한 경우에는 중괄호 {}를 여러 번 중첩해야 합니다.

var person = {
  nameProperty: {
    firstName : {
      firstName001 : 'K',
      firstName002 : 'a',
      firstName003 : 'n',
      firstName004 : 'g'
    },
    middleName :'Jae',
    lastName : 'Seong'
},
  age: 29
};

var { nameProperty : {firstName : {firstName001}}} = person;
  
console.log(firstName001); // "K"

 

아래 코드는 중첩된 구조 분해에서 별칭을 사용할 경우입니다.

var person = {
  nameProperty: {
    firstName : {
      firstName001 : 'K',
      firstName002 : 'a',
      firstName003 : 'n',
      firstName004 : 'g'
    },
    middleName :'Jae',
    lastName : 'Seong'
},
  age: 29
};

var { nameProperty : {firstName : {firstName001 : char001 }}} = person;
  
console.log(char001); // "K"

 

배열의 경우에는 아래와 같이 대괄호 []를 중첩하여 사용합니다.

var numbers = [[1,2,3], [4,5,6]];
var [[first, second], two, three = 3] = numbers;

console.log(`first : ${first}`); // "first : 1"
console.log(`second : ${second}`); // "second : 2"
console.log(`two : ${two}`); // "two : 4,5,6"
console.log(`three : ${three}`); // "three : 3"

객체에서 동적으로 속성 추출

추출해야 하는 속성이 동적일 경우가 있습니다.

아래의 코드는 person.nameProperty.firstName에서 속성의 값을 유동적으로 추출해야 하는 경우입니다.

var person = {
  nameProperty: {
    firstName : {
      firstName001 : 'K',
      firstName002 : 'a',
      firstName003 : 'n',
      firstName004 : 'g'
    },
    middleName :'Jae',
    lastName : 'Seong'
},
  age: 29
};
 
const prop = 'firstName001';
  
var { nameProperty : {firstName : {[prop] : firstNameChar}}} = person;
  
console.log(firstNameChar); // "K"

변수 prop에 추출하고 싶은 속성의 이름을 대입합니다. 그리고 구조 분해에서 추출하고 싶은 속성의 이름이 담긴 변수를 대괄호 []로 감싸서 동적으로 처리하여 추출합니다.

 

아래의 코드는 동일한 결과를 추출합니다.


객체의 구조 분해에서 나머지 속성들 추출

객체를 구조 분해하고 특정 속성을 추출 후 나머지 속성들을 추출하는 경우 스프레드 연산자(...)를 사용하여 추출합니다.

person 객체에서 age를 제외한 모든 속성은 rest라는 변수에 대입됩니다.

var person = {
  nameProperty: {
    firstName : 'Kang',
    middleName :'Jae',
    lastName : 'Seong'
},
  age: 29
};

var {age, ...rest} = person;

console.log(age);
// 29

console.log(rest);
/* result
{
nameProperty: {
    firstName : 'Kang',
    middleName :'Jae',
    lastName : 'Seong'
  }
}
*/

for...of를 사용하여 속성을 추출

const numberObject = [
  { name: 'one' },
  { name: 'two' },
  { name: 'three' },
  { name: 'four' }
];

for (const { name } of numberObject) {
  // ...
}
반응형

댓글