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

김현우·2022년 3월 9일
0

JavaScript

목록 보기
8/8

구조분해할당

배열이나 객체에 들어있는 값들 중 원하는 값만 꺼내서 새로운 변수에 할당하는 문법

위에 적은 한 줄의 설명이 전부다.

이 문법의 핵심은 ‘새로 만드는 변수에 무언가 할당'한다는 것이다. 변수! 할당!

배열이나 객체는 자신만의 구조를 가지고 있고, 그 구조를 부셔버리면 나오는 내용물을 하나씩 집어서 변수에 넣어주는 것이다. 그래서 이름이 ‘구조’ ‘분해’ ‘할당’이다.

문법의 실제 모습을 보자

const [something1, something2] = [1, 2, 5]

console.log(something1, something2)  // 1 2
console.log(something1 + something2) // 3

할당 이라는 것은 = 연산자의 우측에 있는 녀석을 왼쪽 녀석에게 집어넣는다는 것이다.

마찬가지로, 우측에 있는 배열 [1, 2, 3]의 원소들을 좌측의 변수들에 집어넣는다. 변수니까 이름도 마음대로 짓는다.

근데 유심히 보니까 배열의 원소는 세개이고, 변수는 두개만 만들었다.

배열의 첫 원소부터 하나씩 변수에 집어 넣는데, 이 경우에는 변수가 두개니까 두번째 원소까지만 집어넣게 된다.

그럼 반대로 원소보다 많은 변수를 만들면?

const [item1, item2, item3] = [1, 2]
console.log(item1, item2, item3) // 1 2 undefined

item3에는 넣을 원소가 없어서 아무 값도 할당되지 않는다.

배열은 이게 전부이고, 객체의 경우에는 아주 살짝 다르다.

배열은 원소를 순서대로 변수에 할당했는데, 객체에 들어있는 쌍들에는 순서가 없다는 점을 떠올려야 한다.

그럼 어떤 변수에 어떤 값이 들어가는가

  • 변수명은 객체의 키가 되어야 한다.
  • 변수명과 매칭되는 키의 을 할당한다.
const {a, b} = {a: 1, b: 2}
console.log(a, b) // 1 2

모험을 즐기는 편이라면 아래의 코드도 보자

const {a, c} = {a: 1, b: 2}
console.log(a, c) // 1 undefined

c라는 키는 객체에 없으니까 값이 할당되지 않는다.

근데 나는 객체에서 b의 값을 가져다 할당하고 싶은데, 이름을 b가 아니라 위처럼 c라고 짓고싶다. 변수명은 짓는 사람 마음 아닌가!!!

그럼 이렇게 하면 된다. (이때부턴 조금 헷갈릴 수 있다. 믿고 싶은 대로 보지 말고, 보이는 대로 믿자)

const {a, b:c} = {a: 1, b: 2}
console.log(a, b, c) // 1 undfeind 2

위 코드는 다음과 같이 해석된다.

  • 객체의 a값을 변수 a에 담는다
  • 객체의 b값을 변수에 담을 건데, 그 변수 이름은 c라고 하겠다

다음은 뎁스가 좀 있는 객체의 경우다. 우리가 부셔버릴 객체는 ‘결제정보’라는 객체다.

const paymentInfo = {
	price: 3000,
	buyer: {
		name: 'hyeonwoo',
		address: '경기도',
		phone: '01012341234'
	}
}

구매자의 이름, 주소, 휴대폰 번호 중에서 구매자의 이름(buyer.name)과 결재금액(price) 쓰려고 한다. 어떻게 할 수 있을까?

const {price, buyer} = paymentInfo
const {name} = buyer

console.log(price, name) // 3000 hyeonwoo

이렇게 가져다 쓸 수도 있겠다.

아니면 구조분해할당을 쓰지 않고 이렇게 해도 되겠다

const buyerName = paymentInfo.buyer.name
const price = paymentInfo.payment

근데 사실 구조분해할당이라는 문법은 위처럼 쓰기 싫어서 나온 문법인데, 이 경우에는 구조분해할당을 썼을 때랑 쓰지 않았을 때랑 코드 라인 수도 같고, 이럴거면 왜 머리아프게 이런거 익혀서 쓰는지 모르겠다.

구조분해할당 속 구조분해할당

지금부터가 구조분해할당의 꽃이다.

처음 언급한 구조분해할당이란 = 연산자의 우측에 있는 구조체를 부셔서 대상으로 연산자 좌측 변수에 할당하는 것이었다.

근데 변수가 할당받는 값이 또 구조체라면, 그 구조체에 대해서도 구조분해할당을 바로 해버릴 수 있다. 이 때의 작은 구조분해할당은 오로지 = 연산자의 좌측에서만 이루어진다.

배열을 예로 들면 다음과 같이 쓴다.

// 구조분해할당 한번만 사용
const [item1, item2, item3] = [1, [2, 3], 4]
console.log(item1) // 1
console.log(item2) // [2, 3]
console.log(item3) // 4

// 구조분해할당 속 구조분해할당
const [item1, [inner1, inner2], item3] = [1, [2, 3], 4]
console.log(inner1, inner2) //  2 3

객체를 예로 들면, 방금전과 같이 결제금액과 구매자 이름만 쓰고 싶은 경우에는 다음과 같이 구조분해할당을 사용할 수 있다.

const {price, buyer: {name: buyerName}} = paymentInfo

console.log(price, buyerName) // 3000 hyeonwoo
console.log(buyer, name) // undefined undefined

이걸 보는 순간 동공에 지진이 났겠지만, 사실 별거 아니니까 진정하고 차근차근 보자.

값을 할당받을 변수를 적는 곳(=연산자 좌측)에서 콜론(:)이 나오면 둘 중 하나다.

  1. 작은 객체에 대해서 다시 구조분해할당 하겠다.
  2. 변수명을 ‘키이름'이 아니라 다른 이름으로 짓고 싶다.

1번 케이스부터 보자.

buyer : {작은 구조분해할당 세계}

구매자에 관한 정보가 필요하니 buyer라는 키를 적어주었지만,

그 값이 객체라면 나는 그 작은 객체 중에서도 원하는 값만 가져가겠다. 즉, buyer 객체에 대해서 다시 구조분해할당을 하겠다.

라는 의미가 된다. 그래서 콜론 우측에서 다시 구조분해할당에 들어간다.

buyer : {name}

근데 우리는 변수명을 name으로 안 쓰고 buyerName이라고 짓고 싶다. 그래서 {name} 에 대해 2번 케이스를 적용한다.

buyer: {name: buyerName}

구조분해할당은 중첩하지 않고 쓴다면 굉장히 쉬운 문법이다.

다만 객체에 대해 구조분해할당을 중첩해서 사용하는 것은 처음엔 조금 헷갈리므로, 스스로 다시 이해해보고 익숙해지는 시간을 가질 필요가 있다.

0개의 댓글