치춘짱베리굿나이스
비구조화 할당 (구조분해 할당) 본문
비구조화 할당 / 구조분해 할당
배열이나 객체의 속성을 해체하여 개별 변수에 그 값을 담을 수 있는 문법
구조를 분해해서 각각의 원소를 할당하기 때문에 구조분해 또는 비구조화 할당이라고 불린다
쉽게 말하면 오른쪽의 배열 / 객체 원소를 왼쪽의 []
또는 {}
로 감싸진 변수들에 각각 할당해주는 문법이다
배열 비구조화 할당
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를 가져와 대입한다
위의 예시에선 변수명이 name
과 idx
였기 때문에, 우측 객체에서 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
반복문에서 객체의 특정 값만을 이용하기 위해 사용할 수 있다
참고자료
'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 |