본문 바로가기
개발 공부 일지/코어 자바스크립트 (정재남)

[코어 자바스크립트] 데이터 타입 (기본형, 참조형)

by yelimu 2025. 2. 18.
 
코어 자바스크립트
빠르게 발전하고 있으며, 그 중심에는 자바스크립트가 있다고 해도 결코 과언이 아닙니다. ECMAScript2015 시대인 현재에 이르러서도 ES5에서 통용되던 자바스크립트의 핵심 이론은 여전히 유효하며 매우 중요합니다. 《코어 자바스크립트》는 자바스크립트의 근간을 이루는 핵심 이론들을 정확하게 이해하는 것을 목표로 합니다. 기본 이론들 중 ES6에서도 중요성이 높은 핵심 개념을 위주로 다루며, 테크닉이나 요령보다는 원리를 이해하는 데 목적을 두고 있습니다
저자
정재남
출판
위키북스
출판일
2019.09.10

<목표> JS 핵심 개념 정확히 이해하기

  • 데이터 타입, 실행 컨텍스트와 스코프, 호이스팅, 콜백함수, this, 클로저, 프로토 타입
  • 원리를 이해하자
  • 왜? -> 왜? -> ... 깊게 파고드는 집요함을 갖자

  1. 데이터 타입
    기본형 & 참조형
    어떻게 구분되는걸까? : 불변성

bit : 0 또는 1 값을 갖는 메모리 조각
각 비트는 고유한 식별자(메모리 주소값)로 위치를 확인(검색)한다
비트 단위로 위치를 확인하는건 비효율적인 -> 몇개씩 묶자 = byte (8bit)

C/C++, Java : 정적 타입 언어
메모리 낭비 최소화를 위해 데이터 타입 별로 메모리 영역 크기 정해둠

JS: 메모리 용량이 커진 상태에서 등장한 언어, 상대적으로 메모리 관리 필요성 ⬇️


  • 변수 vs. 식별자
    변수 = 변할 수 있는 무언가 (변할 수 있는 데이터)
    식별자 = 어떤 데이터를 식별하는 이름 = 변수명
  • 변수 선언의 동작 원리
    var a; // 변할 수 있는 데이터를 만들고, 이름(식별자)을 a라 한다. undefined반환
    a = '5' // 변경 가능한 데이터가 담기는 공간 = 변수

메모리 관점
변수 영역, 데이터 영역이라는 용어는 이해를 돕기 위한 용어임.

 

1001 이라는 빈 공간을 확보하고, 공간의 이름을 a 라 한다. = 식별자
다른 빈공간 5003에 '5'를 저장하고, 그 주소 (5003)을 a에 저장한다.
변수 a에 접근할때는 a 식별자를 검색

 

왜 변수와 데이터를 별도의 메모리 공간에 저장할까?


JS는
숫자형에 64bit 할당,
문자열에는 미리 할당X (한글, 영어, 글자수에 따라 가변적임)
=> 미리 확보한 공간 내에서만 데이터 변환이 가능하다면 추가로 데이터 크기에 맞게 늘리는 작업이 필요하다
= 예) 1002, 1003에 데이터가 있는 상태에서 1002 에 있는 데이터를 늘리려고하면? 1003에 있는 데이터를 1002 추가할 길이만큼 뒤로 이동한다음에 1002를 늘린다
= 컴퓨터 연산이 많아짐
-> 변수와 데이터를 별도의 공간에 저장하는게 효율적이다

  • 예) 500개 변수마다 숫자 5를 할당한다면
    숫자형 = 8 byte x 500개 = 4000 byte 가 필요함
  • 변수와 데이터를 별도의 공간에 저장하면 (주소 공간의 크기가 2byte라고할때)
    = (500개 x 2 byte) + 8 byte (숫자형) : 500개 변수마다 주소값만 달아주면 되고, 실제 데이터는 1개만 있으면 됨
  • a = 'abc'로 재할당한다면
    5003에 '5'를 수정하는 것이 아니라 새로운 'abc'를 5002에 저장 후 식별자 a 가 바라보는 메모리 주소값을 변경시킨다.
  •  

5003 주소를 참고하는 변수(= 참조 카운트)가 0개이면 가비지 컬렉터 GC의 수거 대상이 된다.

 


변수 vs 상수
변수와 상수를 구분하는 것 = 변경 가능성
(변수는 변하는 데이터, 상수는 변하지않는 데이터)

상수 vs 불변값
기본형 데이터 = 불변성을 갖는다
이때 불변성은 '데이터 영역'의 메모리의 특성이다.
ex. 숫자형, 문자열, boolean, null, undefined, Symbol

var a = 'abc'; // 빈 공간 1001 을 a 라는 식별자로 저장하고 & 빈 공간 5002에 값 'abc'를 저장한다. a 가 @5002 주소값을 바라보게한다.
a = a + 'def'; // 빈공간 5004에 새로운 값 'abcdef'를 저장하고, a 의 값을 @5004로 변경한다.
var b = 5; // 빈공간 1003의 이름을 b라고 한다. & 빈공간 5003에 5를 저장한다 & b에 5003 주소값을 저장한다.
var c = 5; // 빈공간 1004의 이름을 c라고 한다. 데이터 영역에서 5를 찾는다. 이미 만들어놓은 주소를 재활용한다. @5003을 저장한다.
b = 7; // 데이터 영역에서 7을 찾는다. 없다 -> 새로 만든다 5001에 저장한다. -> b가 바라보고 있는 주소값을 5001로 수정한다

각각의 데이터는 다른 값으로 변경할 수 없다 = 불변성 (GC에 의해 수거되지 않는 한)

 

여기서 궁금했던 점

호이스팅은 어떻게 일어나는걸까?
변수 영역에서 해당 변수명이 있는지 먼저 검사하기 때문인가? 그때는 값이 할당된 주소값을 알 수 없나?

const 로 선언한 상수는 변수명 & 주소값<- 여기에 다른 주소값이 못들어오는건가?

const myArr = [] 하고 push 로 값이 추가되는건 ?
const 로 선언해서 주소값 변경이 안된다면 어떻게 데이터가 추가되는걸까?

 


참조형 데이터 = 가변성을 갖는다?

var obj1 = {a:1, b: 'bbb'}

빈 공간 1001 을 확보하고 이름을 obj1라고 한다.
데어터가 여러 프로퍼티로 이루어진 데이터 그룹임 -> 별도의 변수 영역 (@7001 ~ ) 을 마련하고 그 주소를 @5004에 저장한다.
7001과 7002에 각각 이름 a, b라는 프로퍼티 이름을 지정한다. 
데이터 영역에서 1을 검색한다. 없음 -> 빈공간에 저장
7001에 @5002 주소를 저장한다. 


>객체 프로퍼티(변수) 영역만 별도로 갖고, 기존 데이터 영역은 그대로 사용한다. 
>즉 데이터 영역에 저장된 값은 모두 불변값이다.

obj.a = 2; 

7001에 있는 a가 바라보는 주소값은 5001로 바뀜.
그러나 @ 1001 에 있는 obj1 가 바라보는 주소값 @5004 는 바뀌지 않는다. 기존 객체 내부만 바뀜

참조형 데이터는 불변하지 않다.

 

위에서 했던 질문의 답을 알 수 있다.

> - const 로 선언한 상수는 변수명 & 주소값<- 여기에 다른 주소값이 못들어오는건가? 
>   => 그렇다. 처음에 저장한 주소값은 안바뀜
> - const myArr = `[ ]`하고 push 로 값이 추가되는건 ? 
>   const 로 선언해서 주소값 변경이 안된다면 어떻게 데이터가 추가되는걸까? 
>   => 별도의 변수 영역이 존재한다.

 


  • 깊은 복사 (기본형), 얕은 복사(참조형)
  • 복사 과정은 동일하다. 원본 데이터가 변경될 때 결과가 다름 
  • var a = 10; var b = a; // 같은 주소값을 바라봄 = 데이터 = 불변 var obj1 = {c: 10, d:'ddd'} var obj2 = obj1 // 같은 주소값을 바라봄 = 다른 데이터를 참조하고 있음

b = 15;
obj2.c = 20;

 

객체가 바라보는 주소값 @5003 은 바뀌지 않았지만 ( = 불변)
@5003이 바라보는 주소값 @7001~ 안의 변수가 바라보는 주소값이 바뀌었음 
따라서 원본 객체도 데이터가 변하게됨 

 

  • 불변 객체
    객체의 내부 프로퍼티를 바꿔야 할때 새로운 객체를 만들어 할당 => 불변성 확보
    언제 요구되는가?
    ex. 이름을 바꾸는 함수
    1) 객체 프로퍼티에 접근해 값을 수정한다 -> 원본 값이 같이 변경됨
    2) 새로운 객체를 반환하도록 한다 -> 원본 객체 변하지 않음
    3) 중첩된 참조형의 데이터라면? 프로퍼티에 대해서도 새로운 객체를 반환하도록 해야함
    4) JSON -> 문자열 -> JSON 으로 객체를 복사한다


- undefined 
(1) 사용자가 명시적으로 지정 
또는
(2) 자바스크립트 엔진이 자동으로 부여
- 값을 대입하지 않은 변수
  : 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할때
- 객체 내부에 존재하지 않는 프로퍼티에 접근
- return문이 없거나 호출되지 않은 함수의 실행 결과

- 빈 값 ≠ undefined
길이가 3인 배열 Array(3) : `[empty*3]
길이만큼 index 가 있을 것 같지만 특정 index에 값을 지정할때만! 비로소 빈 공간을 확보하고, 인덱스를 이름으로 하고, 데이터가 있는 주소값을 저장한다. (배열은 객체다)

undefined 
(1) 사용자에 의해 명시될때 = 값 자체
(2) JS 엔진에 의해 부여될때 = 값이 없음

var a; 
undefined가 자동으로 할당되는 것이 아님. a에 접근할때 = 값이 할당되지 않은 변수에 접근할 때 반환값으로 undefined를 줄 뿐.

항상 JS 엔진에 부여되는 경우에 해당하도록, 값이 없음을 나타낼 때는 null 을 사용하자


- null
`type of null // object`
js 자체 버그임

var n = null
n == undefined // true
n = null // true

n === undefined // false
n === null // true

 

 

이 포스팅은 <코어 자바스크립트> 를 읽고 내용을 정리한 포스팅입니다.

틀린 내용이 있다면 알려주세요 _ _