[JS] 자바스크립트의 데이터 타입

baegyeong·2024년 6월 29일

Java Script

목록 보기
2/9
post-thumbnail

코어자바스크립트 ch1. 데이터 타입을 읽고 제 생각과 함께 정리한 내용입니다.


  • 기본형: 숫자, 문자열, 불리언, null, undefined, 심볼
    • 값이 담긴 주솟값 복제
  • 참조형: 객체(배열, 함수, 날짜, 정규표현식, Map, WeakMap, Set, WeakSet)
    • 묶음을 가리키는 주솟값 복제

기본형 데이터와 참조형 데이터

불변값

  • 변수와 상수의 차이: 변경 가능성

  • 변경 가능성 판단: 변수 영역 메모리

  • 불변성 여부 판단: 데이터 영역 메모리

    • 데이터 영역에 한번 만들어진 기본값 데이터는 변하지 않는다.
  • 변경 가능성과 불변성은 무슨 차이가 있을까?

  • 또, 이것들을 어떻게 판단할까?

기본형 데이터는 불변값이다.

  • 기존의 불변값에 대한 생각
    • let a = 3 이라고 했을 때, a에 5를 재할당하는 것은 가능하다. 이건 불변성이 깨지는 것 아닌가?
    • 즉 변수 a에 대한 불변성을 생각함
  • 이 책에서 말하고자 하는 것은 기본형 데이터가 불변값이라는 것이다.
    • 위의 예에서 3이라는 값은 5로 수정되는 것이 아니라, 3은 그대로 있고 5라는 새로운 값이 만들어지는 것
    • 값(데이터)이 다른 값으로 변경된 것이 아니라 새로 만들어진 것
  • 한번 만들어진 값은 가비지 컬렉팅을 당하지 않는 한 영원히 변하지 않는다.

가변값

참조형 데이터는 가변, 변경 불가, 불변값으로 활용한다.

  • 참조형 데이터는 ‘객체의 변수(프로퍼티) 영역’이 존재
  • ‘데이터 영역’은 기존의 메모리 공간을 그대로 활용
    • 데이터 영역에 저장된 값이 모두 불변값(기존과 같은 논리)

  • 변수 영역의 데이터 vs 데이터 영역의 데이터
    • 보아하니 둘다 데이터를 저장하는 곳이지만 그 종류가 다른 것 같다.
      • 변수 영역의 값은 데이터 영역의 주소를 저장
      • 데이터 영역의 데이터는 변수 영역의 주소를 저장

  • 가비지 컬렉터
    • 참조 카운트가 0인 메모리 주소
    • 런타임 환경에 따라 특정 시점이나 메모리 사용량이 포화상태에 임박할 때 자동 수거

Javascript에서의 swap

JS에서는 변수영역에 주소값을 저장한다고 했다. 그럼 swap은 어떻게 일어날까?

let a = 10;
let b = 20;
let temp = a;
a = b;
b = temp;

console.log(a, b);
20 10

값을 재할당할 때마다 주소값을 변경하여 swap이 일어나게 한다.

변수가 가리키는 주솟값이 변경되는 것이기 때문에 원본 데이터의 불변성은 지켜진다.

  • swap을 함수로 뺀다면?
let a = 10;
let b = 20;

const swap = (a, b) => {
  let temp = a;
  a = b;
  b = temp;
  
  return a, b;
};

swap(a, b);
console.log(a, b);
10 20

변경되지 않는다! a, b는 지역변수이기 때문에 그렇다고 한다.

  • 인수로 넘겨주고, 바뀐 값을 리턴하는데 왜?
    • 함수 내부에서 a와 b는 복사된 값이다.
    • 책의 변수 복사 챕터에서도 나와있듯이, 기본형은 복사 후 재할당을 하면 원본과 다른 주소값을 바라보게 된다.

함수를 쓰면서 swap을 하려면 어떻게 해야할까?

참조형을 쓴다면?

참조형은 가변값이기 때문에 객체 내부의 프로퍼티를 변경하면 원본값도 변경된다.

let obj = { a: 10, b: 20 };

const swap = (obj) => {
  let temp = obj.a;
  obj.a = obj.b;
  obj.b = temp;
};

swap(obj);
console.log(obj.a, obj.b);
20 10

왜 참조값만 가변이라는 말을 쓸까?

  • 어찌됐건 참조형 데이터도 불변이 아닌가?

  • 주소값을 가리킨다는 점에서, 데이터 측면에서는 둘다 불변인데 왜일까? 라는 고민을 했다.

  • 참조형 객체의 내부 프로퍼티가 가변이라고 할 수 있다.

  • 참조형 데이터가 ‘복사’된 상황에서 가변이라는 상황이 생길 수 있다.

  • 복사한 값의 프로퍼티를 변경하면 원본의 프로퍼티도 변경된다. 이는 자기도 모르게 ‘가변’ 된 것이다.

  • 불변성을 확보하지 못한 것이다.


변수 복사 시 왜 원본의 주소값을 참조하지 않고 원본이 가리키는 주소값을 참조할까?

var a = 10;
var b = a;
  • b는 a의 주소를 참조할 것이라고 예상했으나, a가 가리키고 있는 주소값을 참조함. 즉, a가 참조하고 있는 값을 같이 참조함

  • 왜 a의 주솟값 자체를 참조하지 않을까?

    • 고수준 언어이기 때문에 메모리 주솟값을 직접 다루지 않음
      • 생각해보면 메모리 해제도 가비지 컬렉팅을 통해 한다! (우리가 안한다)
    • c/c++에서는 포인터를 사용하면서 메모리 주소를 직접 다룸
      • 포인터 변수에 메모리 주소를 할당하고, 개발자가 직접 메모리 주소의 실제 값에 접근할 수 있음
      • malloc, free를 통해 직접 메모리 관리함

왜 비어있는 요소는 순회하지 않고, undefined는 순회할까?

  • undefined는 할당된 주소값이 없는건데, 비어있는 것도 똑같은거 아닌가?
    • 일단, undefined는 기본형 데이터이기 때문에 값이다. 따라서 순회한다.
  • 윗 문장의 논리라면 비어있는 요소는 기본형 데이터, 참조형 데이터 중 그 어느 곳에서도 해당되지 않기 때문에 자바스크립트 엔진은 데이터라고 생각하지 않는 것 같다.

let과 const의 초기할당

let과 const에 대해서는 undefined를 할당하지 않은 채로 초기화를 마치며, 특정 값을 할당하기 전까지는 해당 변수에 접근할 수 없다.

  • undefined를 할당하지 않은 채 초기화를 마친다고 한다. 그럼 아예 접근 불가? 그럼 뭐가 뜨는거지?

  • undefined 할당한 거 아닌가?

  • x는 undefined로 초기화된 게 아님

  • 자바스크립트 엔진이 반환하는 값일 뿐이다.

0개의 댓글