[JS] 데이터타입과 메모리할당

yoon Y·2022년 4월 10일
0

JS 학습 내용 정리

목록 보기
1/7

데이터 타입

1. 타입 지정 방법에 따른 언어의 종류

정적 타입 언어

  • 변수의 타입이 type키워드에 따라 결정된다.
  • 실행 전 컴파일 단계에서 처음 정한 type에 맞는 값이 들어있는 지 확인한다
  • 코드 작성 시점에 ide에 의해 검사된다

동적 타입 언어

  • 타입이 실행 중 할당되는 값에 따라 결정된다.
  • 코드를 실행하면서 값이 바뀌면 변수의 type도 달라질 수 있는데,
  • 처음 의도한 type이 아니고 중간에 바뀌었을 경우 실행 중에 예상치 못한 에러를 발생할 수 있다.
  • 코드 작성 시에 확인하기 힘들다

2. JS 데이터 타입 종류

원시타입

  • String
  • Number
  • Boolean
  • Null
  • Undefined
  • Symbol

참조타입

  • 객체
    • 배열
    • 함수
    • Date
    • 정규식
    • Map, WeakMap
    • Set, WeakSet

메모리 할당

1. 변수

변할 수 있는 데이터를 담는 공간(메모리)이다.
하지만 이 데이터 또한 메모리에 담긴다.
변수에 담기는 것은 데이터 메모리의 주소이다.

2. 식별자

메모리의 실제 이름(주소는) 매우 복잡하기 때문에 알아보기 쉽게 별명을 단 것

3. 메모리 구조

모든 메모리는 본인의 이름(주소)를 가지고 있다

변수 메모리 (값의 메모리 주소를 담는 공간)
ㄴ 메모리 주소
ㄴ 식별자
ㄴ 데이터 메모리 주소를 담는 곳

데이터 메모리 (원시타입은 값, 참조타입의 경우 객체 변수 메모리 주소를 담음)
ㄴ 메모리 주소
ㄴ 값을 담는 곳

*값 할당이 되어야 생성됨

참조 타입 전용 변수 메모리 (여러 변수 메모리들을 담는 공간)
ㄴ 메모리 주소
ㄴ 변수
ㄴ 변수
...

*메모리 이름은 첫 변수의 메모리 이름이다


변수 메모리의 가변성

변수 메모리에 담기는 데이터 메모리 주소는 변경될 수 있다.
하지만 상수로 선언할 지 변경 불가능하다.

데이터 메모리의 불변성
데이터 메모리에 값이 한번 담기면 수정할 수 없다.
모든 중복되지 않는 값이 각각 다른 메모리에 담긴다.
아무도 참조하지 않는 데이터 메모리는 가비지 콜렉터가 제거한다.

왜 변수에 직접 값을 담지 않고 데이터 메모리를 한 번 더 거칠까?

한번 값을 할당하면 그 값에 맞춰 메모리 범위가 확보된다.
이미 확보된 데이터 메모리 공간을 할당되는 값에 크기에 맞춰 늘려야하는데,
다른 메모리들의 위치도 옮겨야 할 경우 컴퓨터가 할 연산이 많아지기 때문이다.
변수 영역과 데이터 영역을 분리하면 중복된 데이터에 대한 처리 효율이 높아진다.
매번 새롭게 메모리 크기를 정하고 안쓰는 것은 가비지 콜렉터가 처리하는게 더 효과적이다.


변수 선언 및 데이터 할당 방법

1. 원시타입

let a; // 변할 수 있는 데이터를 담는 메모리를 할당해줘. 그리고 그 메모리의 이름은 a로 해줘
let a = 10; // a메모리에 10할당해줘

선언 단계

  1. 빈 변수 메모리 확보
  2. 식별자 할당

할당 단계

  1. 식별자를 이용해 변수 메모리를 찾음
  2. 데이터 메모리에 해당 값이 있는 지 확인
  3. 변수에 데이터 메모리 주소 할당
    5-1. 있다면 주소를 가져와 변수 메모리에 할당
    5-2. 없다면 데이터 메모리를 새로 만들어 할당 후 변수에 주소 할당

*var는 선언 후 직후 undefind를 할당하고 let, const는 선언만 한 후에 코드 실행 시 초기 값 할당

3줄 요약
1. 변수 메모리 선언
2. 데이터 메모리에 값 할당
3. 변수에 데이터 메모리 주소 할당


2. 참조타입

  1. 변수 공간 확보 및 식별자 지정
  2. 참조타입 값인 걸 확인한 후 객체 변수 영역 확보 (프로퍼티 영역 포함 + 식별자 지정)
  3. 데이터 메모리 확보 후 객체 변수 주소를 값으로 할당
  4. 변수 메모리에 데이터 메모리 주소 할당

이후 프로퍼티에 값 할당 시

  • 데이터 메모리에 값 할당 (이미 있는 경우 생략)
  • 데이터 메모리 주소를 프로퍼티 메모리의 값으로 할당

*객체 변수 영역은 프로퍼티가 생길 때마다 크기가 동적으로 늘어남


원시타입 VS 참조타입

원시타입 값은 데이터 메모리에 이 담김
참조타입 값은 데이터 메모리에 객체 변수 메모리 주소가 담김

왜 원시 타입은 불변값, 참조타입은 가변값이라고할까?

=> 객체의 프로퍼티 변수의 값(메모리 주소)는 변경할 수 있기 때문에 가변적인 것처럼 보이는 것

1. 변수 복사

공통점

원시, 참조 타입 모두 데이터 메모리의 주소가 복사된다는 점은 같다.
데이터 재할당 시에도 다른 값을 넣는다면 다른 데이터 메모리 주소를 새로 할당받기 때문에 문제가 없다.

차이점
문제는 참조타입의 프로퍼티 변수 값을 바꾸게 되면 참조 타입의 메모리 주소를 가지고 있는 모든 변수도 영향을 받는 다는 점이다.

어떤 데이터 타입이든 변수에 할당하기 위해서는 주솟값을 복사해야하기에 js의 모든 데이터 타입은 참조형 데이터일 수 밖에 없다. 원시타입은 주소 복사 과정이 한번만 이루어지고 참조타입은 주소 복사 과정이 한 단계 더 거치게 된다는 점이 다르다.


불변 객체

가변은 프로퍼티를 변경할 때만 성립.
매번 객체를 새로 만들고 프로퍼티를 재할당해야 불변성이 보존 됨.

불변객체가 왜 필요할까?

객체를 복사해서 사용할 때 원본 객체에 변경시키지 않아야 할 때 필요하다.
객체 외부 껍데기와 내부 프로퍼티까지 새롭게 복사되어야 한다.


불변 객체를 만드는 방법은 객체의 얕은 복사, 깊은 복사가 있다.

얕은 복사

객체 복사 시 객체 껍데기와 프로퍼티를 재할당하는데, 바로 아래 단계의 값만 복사하는 것.
참조형 프로퍼티는 재할당하지 않고 메모리 주소를 복사하는 것.

방법1 - for in이용
방법2 - 전개 연산자 사용(1레벨에서만 유효)

깊은 복사

내부의 모든 참조형 프로퍼티까지 재할당하여 복사하는 것.

방법1 - 원시 타입 데이터는 그대로 복사, 참조타입 데이터는 다시 내부 프로퍼티를 재귀적으로 복사해야함.
방법2 - JSON.parse(JSON.stringify(obj)) 의 방식으로 구현할 수도 있다.


undefind와 null

공통점 - 둘 다 값이 없다는 뜻이고 사용자가 직접 부여할 수 있다.

차이점 - undefined는 js엔진이 할당하는 경우가 있다.

→ 구분하기 위해 사용자가 직접 부여할 때는 null을 쓰는 게 좋다.

undefined 할당 경우

  1. undefined는 사용자가 직접 지정하는 경우(값o)
  2. js엔진 자동 부여 경우
    • var선언 후 자동으로 undefined를 부여하는 경우 (값o)
    • 객체 내부의 존재하지 않는 프로퍼티에 접근하는 경우 (값x)
    • return문이 없거나 호출되지 않는 함수의 실행 결과 (값x)

empty vs undefined

  • 아예 값이 없는 empty와 는 다르다!
  • 배열의 길이만 지정했을 때에는 empty가 부여된다
  • undefined(값)도 부여되지 않은 상태로 순회되지 않는다 (순회는 값이 있을 때만)
  • 배열도 객체이고, 객체는 특정 인덱스에 값을 지정할 때 비로소 공간이 생기기 때문
    → 빈 공간 확보 → 식별자 지정 → 데이터 저장 → 데이터 주소 값 저장

*객체의 키에 value를 안넣으면 오류가 나지만 배열은 갯수(인덱스)를 먼저 정할 수 있기 때문

null 사용 시 주의점

  • null의 type은 object임
  • undefined랑은 일치연산자로만 비교가능하다

콜스택의 메모리 구조

자바스크립트는 콜스택메모리힙이라는 메모리 구조를 통해 데이터 및 코드 실행을 관리한다.

콜스택
1. 실행 컨텍스트 (변수 메모리)

  • 스코프 체인 및 this 관리.
  • 코드 실행 순서 관리 등을 수행.
  • 데이터 메모리 주소가 담기는 변수 메모리.
  1. 원시 데이터 메모리
    • 원시 값이나
    • 메모리 힙 주소가 들어감.
    • 한 번 데이터가 할당되면 변경할 수 없음. (불변성)

메모리 힙

  • 참조 타입 데이터 저장하는 메모리
  • 데이터가 늘어날 시 가변적으로 크기가 증가함.
  • 주소는 데이터 메모리에 저장됨.
  • 각 프로퍼티 데이터는 데이터 메모리에 저장되고, 그 주소가 프로퍼티 메모리에 할당됨.

출처: https://curryyou.tistory.com/276?category=898979 [카레유:티스토리]

profile
#프론트엔드

0개의 댓글