패스트 캠퍼스 MGS 3기 - 4월 27일(JavaScript 데이터)

JY·2022년 4월 27일
0

💡 Keyword


  • 구조 분해 할당
  • 전개 연산자(...)
  • 원시 데이터와 참조형 데이터의 불변성
  • 얕은 복사와 깊은 복사(with lodash)



1. 구조 분해 할당

객체 데이터에서의 구조 분해 할당

user라는 객체 데이터에서 내용을 '구조 분해' 해서 내가 원하는(필요한) 속성들만을 꺼내서 사용할 수 있는 것이다. (user.ageuser[age] 같은 방식 외에도 이런 방식으로 데이터에 접근할 수 있다.)
constlet 키워드를 사용해 구조 분해된 내용을 변수로 만들어 활용할 수 있다. (${name}, ${age} ..)

어떤 데이터를 꺼내올 때 만약 그 데이터가 비어있다면 undefined가 출력된다. 이때 할당 연산자를 통해 기본값(address = Korea)을 지정할 수 있다.
만일 객체 데이터에 값이 있다면 객체 데이터에서 할당된 값이 출력된다. (USA)

객체에서 데이터를 꺼내올 때 데이터의 이름을 정확하게 작성하되, 그 데이터의 이름을 그대로 변수 이름으로 활용하고 싶지 않다면 :을 사용하여 변수 이름을 지정할 수도 있다.

배열에서의 구조 분해 할당

객체 데이터가 아닌 배열이므로 구조 분해 시 []를 사용해야 한다.
배열은 객체 데이터와 달리(key: value 형태가 아님!) item이 순서대로 인덱싱 되어 있으므로 꺼내올 순서대로 꺼내오면 된다.
이름으로 구조 분해해서 추출하는 것이 아닌 순서대로 추출하는 것이 객체 데이터와의 큰 차이점이다.

🤔 일부만 추출해서 사용하고 싶다면?
위의 코드에서 'Banana'만 추출해서 사용하고 싶다면 어떻게 해야 할까?
👉 const[, b] = fruits
배열에서의 구조 분해는 순서대로 하는 것이므로 순서를 명시해야 하기에 쉼표를 꼭! 남겨두어야 한다.


2. 전개 연산자


배열 앞에 ...을 붙이면 배열 데이터를 전개하여 쉼표로 구분된 각각의 아이템 형태로 만들어진다.

🤔 전개 연산자 활용
객체 데이터로 변환하는 함수를 만들어보자.
전개 연산자를 사용하지 않는다면 toObject(fruits[0], fruits[1], fruits[2]) 형태로 하나씩 수동으로 넣어주어야 하는 번거로움이 있다.

전개 연산자는 매개변수에 사용할 수도 있다. (이는 'rest parameter'라고 한다.)

위의 함수(toObject())는 다음처럼 축약하여 사용할 수도 있다.


3. 불변성


원시 데이터

  • js에서 사용할 수 있는 기본 데이터를 의미한다.
  • String, Number, Boolean, undefined, null
  • 불변성 ⭕

새로운 원시 데이터를 사용했을 때, 그 원시 데이터가 기존의 메모리 주소에 들어있다면 새로운 메모리 주소에 새롭게 할당하는 것이 아닌 기존에 존재하는 메모리 주소를 바라보도록 만든다.

👉 즉, 원시 데이터는 데이터 자체가 변하지 않는 성질을 가지고 있다. 쉽게 이해하면 생긴 게 같으면 '같다.'고 볼 수 있고, 생긴 게 다르면 '다르다.'고 볼 수 있다.

참조형 데이터

  • Object, Array, Function
  • 불변성 ❌

원시 데이터와 달리 새로운 값을 만들 때마다 새로운 메모리 주소에 할당된다.

  1. 결과: {k: 1} {k: 1} false
    a가 바라보는 메모리 주소와 b가 바라보는 메모리 주소가 서로 다르므로 false

  2. 결과: {k: 7} {k: 7} true
    서로 1번 메모리 주소를 바라보고 있으므로 true

  3. 결과: {k: 2} {k: 2} true
    같은 메모리를 바라보는 여러 변수들이 있을 때, 한 쪽 변수 값을 수정하면 다른 쪽의 변수 값도 수정된다.

  4. 결과: {k: 2} {k: 2} {k: 2} true
    a, b, c 모두 1번 메모리 주소를 바라보고 있다.

  5. 결과: {k: 9} {k: 9} {k: 9} true
    a 변수의 k 속성을 9로 수정했지만 모두 같은 메모리 주소를 바라보고 있으므로 a, b, c 값이 모두 9로 수정된다.

👉 참조형 데이터에서는 할당 연산자를 사용할 때 복사돼서 새로운 객체 데이터가 만들어지는 개념이 아니라 단순하게 메모리 참조 주소만 옮겨간다고 볼 수 있다.

4. 얕은 복사와 깊은 복사


user와 copyUser는 같은 메모리 주소를 바라보고 있다. (user===copyUser 결과: true)

이때 user의 age를 22로 수정하면 user와 copyUser의 age가 모두 22로 수정된다.

얕은 복사

❗ 이러한 현상을 방지하기 위해 '복사'라는 개념을 사용할 수 있다!
.assign()을 이용해 빈 객체에 user를 복사하여 새로운 메모리 주소에 할당한다. (user===copyUser 결과: false)
이제 userage22로 수정해도 copyUserage에는 영향을 미치지 않는다. (userage: 22, copyUserage: 85)

🤔 다음처럼 user 객체를 복사할 수도 있다.


깊은 복사

얕은 복사의 코드에 이어서 useremails를 추가하면 usercopyUser에 모두 추가된 것을 알 수 있다. user의 표면만 복사한 것이므로 이러한 결과가 나타난 것이다.


age는 서로 다르지만 email은 똑같이 추가되었다.

lodash를 이용한 깊은 복사

ref: https://lodash.com/docs/#cloneDeep

터미널에서 lodash를 설치한다.

npm i lodash

import _ from 'lodash'

...

const copyUser = _.cloneDeep(user)

🤔 언제 얕은 복사를 사용하고, 언제 깊은 복사를 사용해야 하지?
객체나 배열 복사 시 그 내부에 또다른 참조 데이터가 없다면 얕은 복사를 사용해도 OK!
그러나 참조 데이터 내부에 또다른 참조 데이터(아래의 emails와 같은)가 있다면 깊은 복사를 고려해야 한다.

profile
🙋‍♀️

0개의 댓글