웹프로그래밍/JavaScript

[JavaScript] 구조 분해 할당(Destructuring Assignment)

정민교 2022. 7. 7. 12:59

개 요

JS에서 다른 js모듈을 require할 때나 비즈니스 로직에서도 빈번하게 사용하는 구조 분해 할당에 대해서 포스팅 하려고 한다. 


개 념

배열이나 객체의 값, 속성(프로퍼티)을 해체해서 해체한 개별의 값들을 변수에 담을 수 있게 하는 표현식이다.

 

배열 구조 분해 할당

let [a, b] = [10, 20];
// a = 10;
// b = 20;

보다시피 굉장히 간단하다. 각각 위치에 맞게 좌측 변수에 우측 값을 (분해하여) 할당한다. 조금 더 응용해보면 아래와 같은 방법으로도 가능하다.

let array = [1, 2, 3];
let [a, b, c] = array;
// a = 1, b = 2, c = 3

 

Rest 파라미터 구조 분해 할당

let array = [1, 2, 3, 4, 5];
let [a, b, ...rest] = array;
// a = 1, b = 2, rest = [3, 4, 5];

Rest 파라미터에 대해서 간략하게 설명을 하면 rest를 직역했을 때 '나머지' 라는 의미를 가지고 있다. 이로 유추해보면 rest 파라미터는 나머지 값들에 대해 처리하는(받는) 변수(파라미터)라고 볼 수 있다. 위의 코드로 보면 1과 2는 각각 변수 a, b에 구조 분해 할당 되었지만 3, 4, 5 나머지 값들은 rest 변수에 배열 형태로 저장되는걸 확인할 수 있다.

 

기존 배열에서 특정 인덱스값을 할당할 때의 비교

/* 배열에서 index를 지정해 할당 */
let array = [1, 2, 3, 4, 5];
let test = array[0];
// test = 1

/* 구조분해할당을 이용 */
let array = [1, 2, 3, 4, 5];
let test = array;
let [test2, test3] = array;
// test = 1
// test2 = 2, test3 = 3

기존 배열에서 특정 인덱스 값을 할당할 때는 상단 코드와 같이 배열의 인덱스를 따로 지정해주어 사용했지만 구조분해할당을 이용하면 하단 코드와 같은 할당이 가능해 코드 간소화가 가능하다.  구조분해할당을 사용할 때는 기본적으로 기존 배열의 첫번째 인덱스부터 차례로 할당하기 때문에 test2와 test3 변수에는 array배열의 첫번째와 두번째 값인 1, 2가 차례로 할당되고 나머지 3, 4, 5 값은 할당이 되지 않는다.

 

객체에서의 구조 분해 할당

언젠가 타인이 작성한 코드를 분석할 때 상단 모듈 선언부(require)에 아래와 비슷한 코드를 본 적이 있을 것이다.

const { object1, object2 } = require('exampleModule');

앞서 설명한 배열에서의 구조 분해 할당을 잘 이해했다면 객체에서의 구조 분해 할당도 어렵지 않게 이해가 가능할 것이다. 먼저 구조분해할당을 사용하지 않았을 때 기존 객체에서 새로운 변수에 값을 할당할 때는 어떤 식으로 사용했는지 아래 코드를 확인해보자.

const obj = {
    name : "gyo",
    sex : "male",
    age : 99
};

const myName = obj.name;
const mySex = obj.male;
const myAge = obj.age;
// myName = "gyo", mySex = "male", myAge = 99

구조분해할당을 사용하지 않았을 때는 해당 객체의 프로퍼티에 직접적으로 접근해 변수에 값을 할당한다. 물론 이와 같은 방법도 좋지만 코드의 간소화를 위해 구조분해할당을 사용해 아래와 같이 사용이 가능하다.

let obj = {
    name : "gyo",
    sex : "male",
    age : 99
};

const { name, sex } = obj;
// name = "gyo", sex = "male"

/* 순서가 바뀌었을 때 */
const { sex, name } = obj;
// name = "gyo", sex = "male"

기존 객체 obj를 새로운 변수에 구조분해할당을 사용하면 obj에서 분해된 각각 프로퍼티의 key 이름과 동일한 변수명에 알아서 할당을 해준다. 또한 배열 구조분해할당과 다르게 값을 할당받는 변수들의 순서가 바뀌어도 프로퍼티의 key이름 기준으로 할당하기 때문에 하단 코드와 같이 할당이 된다. 

여기서 만약 프로퍼티명과 동일한 변수명을 사용하지 않고 새로운 변수명으로 할당을 받고 싶다면 아래와 같이 코드를 작성하면 된다.

let obj = {
    name : "gyo",
    sex : "male",
    age : 99
};

const { name: myName, age: myAge, sex: mySex } = obj;
// myName = "gyo", myAge = 99, mySex = "male"

또한 배열에서 구조분해할당과 동일하게 rest 파라미터도 사용가능하다.(ES9 도입) 이 부분은 배열 구조분해할당과 크게 차이가 없으니 아래 코드 예시만 작성하겠다.

let obj = {
    name : "gyo",
    sex : "male",
    age : 99
};

const { name, ...rest } = obj;
// name = "gyo", rest = { sex : "male", age : 99 }

객체 구조분해할당은 여기서 마무리 하고 앞서 이야기한 상단 모듈 선언부(require)에서 사용한 객체 구조 분해할당은 결국 해당 모듈에서 할당받을 변수명과 같은 프로퍼티 이름을 찾아 할당한다고 볼 수 있다.


참고 포스팅

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

https://chanhuiseok.github.io/posts/js-10/