구조 분해 할당 - 객체, 배열, JSON

조 은길·2021년 3월 1일
1

Javascript 정리

목록 보기
17/48
post-thumbnail

내 생각에, 구조 분해 할당은 Spread operator과 Rest Parameter의 응용법 중 하나라고 생각한다.
그런 이유로, 아직 Spread operator과 Rest Parameter에 대한 이해가 부족하다면, 아래의 링크로 보고 오시는 것을 추천한다.

Spread operator 와 Rest Parameter


Destructuring assignment (구조분해할당)

MDN에 따르면,

구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.

즉, 구조분해할당은 "배열이나 객체에 있는 값을 다시 새로운 변수에 할당받아서 사용할 수 있는 문법"이다.

배열에서 구조분해할당 사용하기

- 전통적인 배열의 요소값을 받는 방식

let arr = ["홍길동", "이순신", "홍길자", "김철수"];

 let n1 = arr[0];
 let n2 = arr[3];
 console.log( n1, n2 ); // 홍길동 김철수

// 적용할 값을 우측에 두고, 좌측에는 요소 정보를 적어서 꺼내오는 방식
// arr이 배열이기 때문에, 좌측도 배열 형식이어야 함

- 구조분해할당을 통한 배열 요소값 할당 방식

적용할 값을 우측에 두고, 좌측에는 요소 정보를 적어서 꺼내오는 방식이다.

아래의 예시는 arr이 배열이기 때문에, 좌측도 배열 형식이어야 한다.

let arr = ["홍길동", "이순신", "홍길자", "김철수"];
// 위치 요소를 반환받아서 a b c d 변수에 저장
let [a, b, c, d] = arr;

console.log(a, b, c, d); // 홍길동 이순신 홍길자 김철수

- 배열 요소 중 원하는 값만 꺼내오기

let arr = ["홍길동", "이순신", "홍길자", "김철수"];

// 또한, 원하는 값만도 꺼내 올 수 있다.
let [n1, , , n2] = arr;

console.log(n1, n2); // 홍길동 김철수

// 전부다 반환받는다.
let [...x] = arr;

console.log(x); // ["홍길동", "이순신", "홍길자", "김철수"]

// all 에는 첫번쨰와 두번째 요소를 제외한 나머지 요소들을 배열의 형태로 할당 받는다.
// ** rest parameter 는 항상 무조건 마지막에만 사용해야한다.

let [k1, k2, ...all] = arr;
console.log(k1, k2, all); // 홍길동 이순신 ["홍길자", "김철수"];

객체에서 구조분해할당 사용하기

구조분해할당은 객체에서 강력한 힘을 발휘한다.

// destructuring(객체에서 사용하기)

let obj = { name: "홍길동", age: 20 };

 console.log(obj["name"]); // '홍길동'
 console.log(obj.name); // '홍길동'

복잡한 객체에서 value 추출하기

const example = { a: 123, b: { c: 135, d: 146 } };

const { a , b : { d } } = example;

console.log(a); // 123

console.log(d); // 146

만약 d의 값을 다른 이름으로 추출하고 싶다면??

const example = { a: 123, b: { c: 135, d: 146 } };

const { b : { d : newname } } = example;

console.log(newname); // 146

배열과 마찬가지로, 적용할 값을 우측에 두고, 좌측에는 요소 정보를 적어서 꺼내오는 방식

아래의 예시에서 obj가 객체이기 때문에, 좌측도 객체 형식이어야 함

객체 내의 value 값 추출하기

추출하고 싶은 key 값을 짚어넣어주면, 해당 key이 가진 value 그대로 가지고 와준다.

let obj = { name: "홍길동", age: 20 };
// key 값을 짚어넣어주면, 해당 key 값을 그대로 가지고 와줍니다.
 let {name} = obj;
 console.log( name );
// 이렇게 객체에서 홍길동만을 추출했다.
 name = '홍길동'

name과 age를 꺼내고 싶다면??

 let obj = { name: "홍길동", age: 20 };
 let { name, age } = obj;
 console.log(name, age); // '홍길동' 20

**spread operator 문법을 사용할 수도 있다.

 let obj = { name: "홍길동", age: 20 };
 let { ...arr } = obj;
 // arr이 객체 안에 있는 변수를 다 가지고 들어왔다.

 console.log(arr); // { name: '홍길동', age: 20 }

그런데, 맨날 우리는 같은 key 값을 지정해서 값을 가지고 와야 하는가??

이름을 변경해서 쓰는 형태로도 적용을 시킬 수 있다.

이름을 변경하지 않고, key에 해당하는 value값을 뽑아오는 방식

let person = {
  name: "김철수",
  age: 30,
  job: ["programmer", "designer"],
  info: { id: "kkk123", email: "namer" },
};

// 필요한 부분만 뽑아오기
 let { name, age, job } = person;
 console.log(name, age, job);

이름을 변경하여, value값을 뽑아오는 방식

아래와 같이, 콜론 문법으로 객체의 value를 새로운 이름으로 뽑아낼 수있다.

// 새로운 방식
// name을 다른 이름으로 가져오기

// 콜론 문법으로 객체를 새로운 이름으로 뽑아낼 수있다.
// 좌측에 있는 게 key 값이고, 우측에 있는 게 새로운 이름

let person = {
  name: "김철수",
  age: 30,
  job: ["programmer", "designer"],
  info: { id: "kkk123", email: "namer" },
};

let { name: aaa } = person;
console.log(aaa); //  '김철수'

let { age: bbb, job: xxx } = person;
console.log(bbb, xxx); // 30 [ 'programmer', 'designer' ]

JSON 파일에서 구조분해할당 사용하기

대부분의 JSON 파일은 배열과 객체가 혼합되어있다.

또한, API문서를 받아오면, 알겠지만 JSON 형태는 왠만해서는 굉장히 복잡하다.
이런 JSON을 우리가 원하는 값만 어떻게 추출할 수있는지 알아보자!!!

list는 2개의 객체를 요소를 가진 배열이다. 이 배열에서 2번째 요소만을 추출해보자!!

let list = [
  {
    num: 1,
    title: "hello",
    info: ["banana", "apple"],
    profile: { birth: "20201111", img: "https://www.test.com/1" },
  },
  {
    num: 1,
    title: "hello",
    info: ["melon", "orange"],
    profile: { birth: "20201212", img: "https://www.test.com/2" },
  },
];

let [, a] = list;
console.log(a);
/* {
  num: 1,
  title: 'hello',
  info: [ 'melon', 'orange' ],
  profile: {
    birth: '20201212',
    img: 'https://www.test.com/2'
  }
} */

2번째 index에서 num과 title만 뽑고 싶을 때는 어떻게해야 할까??


let list = [
  {
    num: 1,
    title: "hello",
    info: ["banana", "apple"],
    profile: { birth: "20201111", img: "https://www.test.com/1" },
  },
  {
    num: 1,
    title: "hello",
    info: ["melon", "orange"],
    profile: { birth: "20201212", img: "https://www.test.com/2" },
  },
];

let [, { num, title, info }] = list;

console.log(num, title, info); // 1 'hello' [ 'melon', 'orange' ]

list에서 'orange'만 뽑고 싶을 때는??

객체를 뽑을 때 이름을 바꾸고 싶을 떄는 : 를 사용해서 뽑지만, 배열의 경우는 더 쉽다.

// 'orange'만 뽑고 싶을 때는??
// 객체를 뽑을 때 이름을 바꾸고 싶을 떄는 : 를 사용해서 뽑지만,
// 배열의 경우는 더 쉽다.

let list = [
  {
    num: 1,
    title: "hello",
    info: ["banana", "apple"],
    profile: { birth: "20201111", img: "https://www.test.com/1" },
  },
  {
    num: 1,
    title: "hello",
    info: ["melon", "orange"],
    profile: { birth: "20201212", img: "https://www.test.com/2" },
  },
];

// 객체처럼 콜론을 사용해줄 필요도 없다. 왜냐면, 배열은 위치를 통해서 무엇을 할당받는지 알기 때문!!

let [ , { info: [m, orange], } ] = list;

console.log(m, orange); // 'melon' 'orange'

2번째 index에서 profile이라는 객체안의 birth를 뽑고 싶다면??

let list = [
  {
    num: 1,
    title: "hello",
    info: ["banana", "apple"],
    profile: { birth: "20201111", img: "https://www.test.com/1" },
  },
  {
    num: 1,
    title: "hello",
    info: ["melon", "orange"],
    profile: { birth: "20201212", img: "https://www.test.com/2" },
  },
];

// 2번째 index에서 profile이라는 객체안의 birth를 뽑고 싶다면??
let [ , { profile: { birth, img }, } ] = list;

console.log(birth, img);  // '20201212' 'https://www.test.com/2'

birth와 img를 다른 이름으로 a1과 a2로 뽑아내고 싶다면??

let [ , { profile: { birth: a1, img: a2 } } ] = list;

console.log(a1, a2); // '20201212' 'https://www.test.com/2'

Destructuring 응용법

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

console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];

console.log(rest); // [30,40,50]

({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}

구조 분해 할당시, 주의사항

this는 함수가 호출 될 때, 어떻게 호출되었냐에 따라 나오는 값이 달라진다.

위와 같은 경우는, 구조 분해 이후에, getCandy()를 호출하게 되면, 원하는 값이 안 나올 수도 있다.

결론은, this 가 있는 경우는 구조 분해 할당은 안 하는 게 정답이다.

공부하면 할수록, this는 문제가 많은 문법이다.


글을 마치며

구조 분해 할당은 앞으로도 많이 쓸 문법이기 때문에, 헷갈릴 때마다 찾아볼 수 있도록 정리했다.

Spread operator과 Rest Parameter과 겹치는 부분과 많고, 중복해서 쓴 부분도 많다. 그만큼 중요하고, 잊어버리지 않게끔 스스로 강조하고 싶었다. 혹시나, 내용이 좀 반복된다면, 너그럽게 이해하고 넘어가주시길 바랍니다.

자료 출처 및 참고 자료

profile
좋은 길로만 가는 "조은길"입니다😁

0개의 댓글