Frontend/JavaScript

[JavaScript] 코어 자바스크립트 1장 - 데이터 타입

zeo.y 2023. 5. 24. 17:26
반응형

아래 책을 읽고 정리한 내용입니다.
http://www.yes24.com/Product/Goods/78586788

코어 자바스크립트 - YES24

자바스크립트의 근간을 이루는 핵심 이론들을 정확하게 이해하는 것을 목표로 합니다최근 웹 개발 진영은 빠르게 발전하고 있으며, 그 중심에는 자바스크립트가 있다고 해도 결코 과언이 아니

www.yes24.com

 
 

💡 자바스크립트가 데이터를 처리하는 과정을 통해 기본형과 참조형 타입이 서로 다르게 동작하는 이유를 이해할 수 있다.

 

데이터 타입의 종류

자바스크립트의 데이터 타입은 크게 두 가지가 있다.

기본형 (Primitive Type)Number, String, Boolean, null, undefined, Symbol
참조형 (Reference Type)Object (Array, Function, Date, RegExp, Map, Set)

 
일반적으로 두 타입을 구분할 때 기본형은 불변값, 참조형은 가변값이라고 한다. 하지만 이러한 구분을 정확하게 이해하기 위해서는 불변성이 무엇인지부터 알아야 하며, 불변성을 이해하기 위해서는 메모리 관점에서 데이터가 저장되는 방식을 먼저 이해해야 한다.
 
 

데이터가 저장되는 방식

우선 값을 저장할 메모리를 변수 영역과 데이터 영역을 구분해야 한다. 변수를 저장할 공간을 변수 영역, 실제 데이터를 저장할 공간을 데이터 영역이라고 생각하면 된다.
 

변수 선언 및 데이터 할당

var a;
a = 'abc';

 
위 명령을 받은 컴퓨터는,
 

1. 변수 영역 메모리에서 비어있는 공간(@1003) 하나를 확보

2. 이 공간(@1003)에 a라는 이름을 부여

3. 데이터 영역 메모리에서 비어있는 공간(@5004) 하나를 확보

4. 확보한 공간(@5004)에 문자열 'abc'를 저장

5. 변수 영역에서 a라는 식별자를 검색 (@1003)

6. 'abc'를 저장한 주소(@5004)를 a의 공간(@1003)에 대입

 

변수 영역주소1002100310041005
데이터 이름: a
값: @5004
  
데이터 영역주소5002500350045005
데이터  'abc' 

 
이렇게 변수 영역과 데이터 영역을 나누어 관리하는 이유는 데이터 변환을 자유롭게 할 수 있게 함과 동시에 메모리를 더욱 효율적으로 관리하기 위함이다. 특히 중복된 데이터에 대한 처리 효율이 높아진다.
 

기존 문자열을 변경할 때는 무조건 새로 만들어 별도의 공간에 저장하고 그 주소를 변수 영역에 연결한다. 예를 들어 위의 a라는 변수를 'abcdef'로 변경한다면, 아래와 같은 과정이 발생한다.

 

1. 데이터 영역 메모리에서 비어있는 공간(@5005) 하나를 확보

2. 확보한 공간(@5005)에 문자열 'abcdef'를 저장

3. 변수 영역에서 a라는 식별자를 검색 (@1003)

4. 'abcdef'를 저장한 주소(@5005)를 a의 공간(@1003)에 대입

 
 

불변성

메모리 관점에서 값은 변수 영역과 데이터 영역으로 구분되어 저장된다는 것을 알아보았다. 이를 기반으로 불변성에 대해 알아보자.
 

불변성의 여부를 구분할 때의 변경 가능성의 대상은 데이터 영역의 메모리이다. 따라서 기본형 데이터는 불변값이다. 변경은 새로 만드는 동작을 통해서만 이루어지기 때문이다. 한 번 만들어진 값은 가비지 컬렉팅을 당하지 않는 한 영원히 변하지 않는다. (위에서 변수 a를 'abc'에서 'abcdef'로 바꿀 때, 기존 값인 'abc' 변하지 않았다는 것을 보면 무슨 말인지 이해할 수 있다. 기본형 타입인 string이 불변값임을 확인할 수 있는 것!)

 
그렇다면 가변값은? 예시를 확인해 보자.

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

위 명령을 받은 컴퓨터는,
 

1. 변수 영역 메모리에서 비어있는 공간(@1002) 하나를 확보

2. 이 공간(@1002)에 obj1라는 이름을 부여

3. 데이터 영역 메모리에서 비어있는 공간(@5003) 하나를 확보

4. 데이터를 저장하려고 했는데 그룹이네? 이 그룹 내부 프로퍼티들을 저장하기 위해 별도의 변수 영역 확보(@7103~?)

5. 확보한 공간(@5003)에 데이터 그룹 주소(@7103~?)를 저장

6. (@7103~?)에 각각 a와 b프로퍼티 이름 부여

7. 데이터 영역에서 숫자 1 검색 -> 없으면 주소 확보 후 저장, 있으면 해당 주소 확보 (@5003)

8. 데이터 영역에서 문자열 'abc' 검색 -> 없으면 주소 확보 후 저장, 있으면 해당 주소 확보 (@5004)

9. (@7103~?)에 각각 a와 b에 대응하는 데이터 주소(@5003, @5004) 대입

 
 

변수 영역주소1001100210031004
데이터 이름: obj1
값: @5001
  
데이터 영역주소5001500250035004
데이터@7103 ~ ? 1'bbb'
변수 영역주소7103710471057106
데이터이름: a
값: @5003
이름: b
값: @5004
  

 

obj1의 프로퍼티들은 데이터 영역에 주소(@7103~?)로 저장되어 있는 것을 볼 수 있다. 이 주소 값자체는 변하지 않는다. 그러나 변수에는 다른 값을 얼마든지 대입할 수 있다. 이후 obj1.a = 2라는 연산을 수행하면, @5002에 2가 저장되고 @7103의 값이 @5002로 변경될 것이기 때문이다. 바로 이 부분 때문에 참조형 타입을 불변하지 않다(가변값이다)라고 하는 것이다.

 

변경은 새로 만드는 동작을 통해서만 이루어지는 것이 불변값의 성질이다. 하지만 obj1.a = 2를 통한 변경은 새로운 객체가 만들어진 것이 아니라 기존 객체 내부 값만 바뀐 것이기 때만에 불변값이 아닌 것이다. 따라서 참조형 타입은 가변값이다.

 
 

기본형과 참조형의 차이점

변수 복사 후 값을 변경하는 행위를 통해 기본형 타입과 참조형 타입의 차이점을 조금 더 알아보자. 변수를 복사하는 과정은 동일하지만 데이터 할당 과정에서 이미 차이가 있기 때문에 복사 이후 동작에도 큰 차이가 있다.
 

var a = 10;
var b = a;
var obj1 = { c: 10, d: 'ddd'};
var obj2 = obj1;

b = 15;
obj2.c = 20;

console.log(a === b); //false
console.log(obj1 === obj2); //true

 
기본형 타입인 a와 b는 서로 다른 주소를 바라보게 되었고, 참조형 타입인 obj1과 obj2는 여전히 같은 객체를 바라보고 있는 상태이다. 이 결과가 기본형과 참조형의 가장 큰 차이점이다. 기본형은 주솟값을 복사하는 과정이 한 번만 이뤄지고, 참조형은 한 단계를 더 거치게 된다는 것이다.
 
 
참고) 무조건 참조형 타입이 가변값이라고는 할 수 없다.

  • obj2 = obj1이 아니라 obj2 = { c: 20, d: 'ddd' } 처럼 객체 자체를 할당함으로써 값을 직접 변경했을 때에는 메모리의 데이터 영역의 새로운 공간에 새 객체가 저장되고 그 주소를 변수 obj2 위치에 저장하게 되기 때문이다. 
  • 참조형 데이터가 가변값이라고 설명할 때의 "가변"은 데이터 내부의 프로퍼티를 변경할 때만 성립하는 것이다.

 
 

반응형