치춘짱베리굿나이스

비구조화 할당 (구조분해 할당) 본문

Javascript + Typescript/이론과 문법

비구조화 할당 (구조분해 할당)

치춘 2022. 4. 12. 13:04

비구조화 할당 / 구조분해 할당

배열이나 객체의 속성을 해체하여 개별 변수에 그 값을 담을 수 있는 문법

구조를 분해해서 각각의 원소를 할당하기 때문에 구조분해 또는 비구조화 할당이라고 불린다

쉽게 말하면 오른쪽의 배열 / 객체 원소를 왼쪽의 [] 또는 {} 로 감싸진 변수들에 각각 할당해주는 문법이다

배열 비구조화 할당

let [a, b] = [1, 2]
// a = 1, b = 2

좌측 배열의 길이와 우측 배열의 길이가 같을 경우, 순서대로 일대일 대응한다

let [a, b, c] = [1, 2, 3, 4, 5]
// a = 1, b = 2, c = 3

좌측 배열의 길이가 우측 배열의 길이보다 짧을 경우, 좌측 배열 기준으로 값을 할당한다

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

좌측 배열의 길이가 우측 배열의 길이보다 길 경우, 우측 배열의 인덱스를 넘어가는 변수에 undefined가 대입된다

let [a, b, ...c] = [1, 2, 3, 4, 5, 6, 7]
// a = 1, b = 2, c = [3, 4, 5, 6, 7]

스프레드 구문을 사용하면, 해당 변수의 인덱스부터 끝까지 잘린 배열이 대입된다

스프레드 구문은 구조분해 할당의 맨 끝에만 올 수 있다

객체 비구조화 할당

let {name, idx} = {greetings: "hello", name: "chichoon", gender: "secret", idx: 10}
// name = "chichoon", idx = 10

우측 객체로부터 좌측 객체의 변수명을 Key값으로 갖는 value를 가져와 대입한다

위의 예시에선 변수명이 nameidx였기 때문에, 우측 객체에서 key가 name, idx인 value를 각각 가져와 대입한 것

배열의 비구조화 할당과 다르게 변수의 중간에 전개 연산자를 사용할 수 없다

let {name: nickname, idx: n} = {greetings: "hello", name: "chichoon", gender: "secret", idx: 10}
// nickname = "chichoon", n = 10

좌측 객체에 value를 입력할 경우 다른 이름으로 변수를 저장할 수 있다

const key = 'space bar';
let {[key]: space_bar, idx} = {'space bar': 20, nickname: "aaa", idx: 15}
// space_bar = 20, idx = 15

let {['space bar']: space_bar, idx} = {'space bar': 20, nickname: "aaa", idx: 15}
// space_bar = 20, idx = 15

우측 객체의 key값에 특수기호 등 변수명으로 사용할 수 없는 문자열이 있을 경우, 원하는 key값을 대괄호로 감싸 명시해준 후 매칭할 변수명을 옆에 적는다

매칭할 변수명이 없을 경우 에러가 발생한다

({a, b, c}) = {a: 123, c: 345, b: 567};
// a = 123, b = 567, c = 345

좌측 변수 선언 시 선언에 대한 명시 (var, let, const) 가 없을 경우 소괄호 (()) 로 한번 더 감싸줘야 한다

기본값 설정

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

let {a, b, c = 10} = {a : 14, b : 15};
// a = 14, b = 15, c = 10

인덱스를 넘어가거나 존재하지 않는 key 값에 대해 undefined를 반환하는 것을 방지하기 위해 미리 값을 초기화시켜 줄 수 있다

깊은 복사

let arr = [[1, 2], [1, 3], [1, 4]];
let arr2 = [...arr];

arr2[0][0] = 5;
// arr = [[1, 2], [1, 3], [1, 4]];
// arr2 = [[5, 2], [1, 3], [1, 4]];

let obj = {a: 1, b: 2, c: 3};
let obj2 = {...obj};

obj2.a = 5;
// obj = {a: 1, b: 2, c: 3};
// obj2 = {a: 5, b: 2, c: 3};

얕은 복사로 인해 원본의 값까지 변경되는 것을 원치 않을 때, 전개 연산자와 구조분해 할당을 통해 깊은 복사를 할 수 있다

let obj = {a: 1, b: 2, c: 3};
let obj2 = {...obj, b: 5};

// obj = {a: 1, b: 2, c: 3};
// obj2 = {a: 1, b: 5, c: 3};

객체의 깊은 복사 시에 값을 같이 바꿔줄 수 있다

용례

일반적인 용례

let input = "2 3";
let [n, m] = input.split(" ").map(Number);
// n = 2, m = 3

좌항 [n, m] 이 할당할 값, 우항 (input.split(” “).map(Number)) 이 분해할 배열

함수

const foo = ({a, b}) => {
    console.log(a);
    console.log(b);
};

foo({a: 10, b: 5, c: 3});
// 10
// 5

함수에서 변수를 받아올 때 구조분해 할당을 사용할 수 있다

반복문

const data = [{user: "a", idx: 1}, {user: "b", idx: 2}, {user: "c", idx: 3}];
for (let {user: v} of data) {
    console.log(v);
}
// a
// b
// c

반복문에서 객체의 특정 값만을 이용하기 위해 사용할 수 있다


참고자료

자바스크립트 {...} [...] 문법 (비구조화 할당/구조분해 할당)

06. 비구조화 할당 (구조 분해) 문법

'Javascript + Typescript > 이론과 문법' 카테고리의 다른 글

Throttle & Debounce  (0) 2022.05.18
비동기 처리와 Promise  (0) 2022.05.13
[Typescript] Type vs Interface  (0) 2022.05.09
spread, rest  (0) 2022.04.12
null, NaN, undefined 차이  (0) 2022.03.25
Comments