본문 바로가기
FRONT-END/JavaScript

01. 데이터 타입 (코어 자바스크립트)

by 랄라J 2024. 9. 16.

책을 읽은지는 꽤 지났지만, 다시한번 복습 겸 기록을 남겨보려고 합니다. 책을 읽고 요약해 정리한 내용의 전문은 제 개인 노션에 정리해놓았습니다.

 

데이터 타입

데이터 타입의 종류

자바스크립트 데이터 타입의 종류는 기본형(Primitive Type)과 참조형(Reference Type)으로 나뉜다.

기본형에는 number, string, boolean, null, undefined, Symbol이 있고,

참조형에는 object(array, function, Date, RegExp, Map, WeakMap, Set, WeakSet)이 있다.

데이터를 할당하거나 연산 시 기본형과 참조형 모두 복제를 한다.

기본형은 값이 담긴 주솟값을 바로 복제하고, 참조형은 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제한다.

 

메모리와 데이터

컴퓨터는 모든 데이터를 0과 1로 바꿔 기억한다. 0과 1로 표현할 수 있는 하나의 메모리 조각을 bit라고 한다.

메모리는 수많은 bit로 구성되어있고, 각 bit는 고유한 식별자를 통해 위치를 확인할 수 있다.

하지만 0, 1만 표현할 수 있는 bit 단위로 위치를 확인하는 것은 비효율적이기 때문에 8개의 bit를 묶어 1byte로 표현한다.

1byte로 표현함으로써 표현할 수 있는 값(1byte는 2⁸로 256개의 값을 표현)이 늘어나고, 검색시간 줄이기도 가능하다.

모든 데이터는 메모리의 주솟값을 통해 서로 구분하고 연결할 수 있다.

자바스크립트는 숫자는 8byte(64bit), 문자열은 특별히 정해진 규격 없이는 영어는 1byte, 한글은 2byte를 사용한다.

 

변수, 식별자

변수는 변할 수 있는 수로 변경 가능한 데이터가 담길 수 있는 공간을 의미하고,

식별자는 어떤 데이터를 식별하는데 사용하는 이름으로 변수명을 의미한다.

 

변수 선언과 데이터 할당

var a;
a = '123'
변수 영역 주소 1001 1002 1003
데이터 이름 : a
값 : @5002
   
데이터 영역 주소 5001 5002 5003
데이터   '123'  

변수를 선언하는 과정은 메모리에서 비어있는 공간을 확보하고, 해당 공간의 이름을 a로 지정한다.

변수에 데이터를 할당하는 과정은 데이터를 지정하기 위한 별도의 메모리 공간을 확보하고 문자열을 저장한다.

그리고 해당 주소를 변수 영역의 데이터 값에 저장한다.

 

값에 직접 지정하지 않고 한단계를 더 거치는 이유는 데이터 변환을 자유롭게 할 수 있게함과 동시에 메모리를 더욱 효율적으로 사용하기 위함이다. 변수 영역과 데이터 영역의 분리로 중복된 데이터에 대한 처리 효율이 높아진다.

변경은 새로 만드는 동작을 통해서만 이루어지는데 이는 불변값의 성질이다.

 

변수와 상수

변경 가능성이 있다면 변수, 없다면 상수로 구분되는데 이때 변경 가능성의 대상은 변수 영역의 메모리를 의미한다.

즉, 한번 데이터 할당이 이루어진 변수 공간에 다른 데이터를 재할당할 수 있는지가 관건이다.

불변성의 여부 대상은 데이터 영역의 메모리를 의미한다.

var a = 'abc';
a = a + 'def'; // 새로운 문자열 생성 후 그 주소를 a에 저장

var b = 5 // 데이터 영역에 5를 찾고 없다면 만들어 저장
var c = 5 // 데이터 영역에 5를 찾고 있으면 재활용
b = 7 // 데이터 영역에 7를 찾고 없다면 만들어 저장

 

가변값

참조형은 기본적으로 가변값이나 설정에 따라 불가능한 경우도 있고, 불변값으로 활용하는 경우도 있다.

 

참조형 데이터 변수 할당 및 재할당

var obj1 = { a = 1, b = 'bbb' }
obj1.a = 2
변수 영역 주소 1001 1002 1003 1004
데이터   이름: obj1
값 : @5001
   
데이터 영역 주소 5001 5002 5003 5004
데이터 @7103 ~ ? 1 'bbb'  
객체 @5001의
변수영역
주소 7103 7104 7105 7106
데이터 이름 : a
값 : @5002
이름 : b
값 : @5003
   

변수 영역에 빈 공간을 확보하고 이름을 obj1으로 지정한다.

5001에 저장하려고 보니 여러개의 프로퍼티로 이루어진 데이터 그룹이므로 별도의 5001 변수 영역 마련 후 그 영역의 주소를 저장한다.

7103, 7104에 a, b 프로퍼티 이름을 지정한다.

데이터 영역에 저장 및 값으로 해당 주소를 저장한다.

변수 영역 주소 1001 1002 1003 1004
데이터   이름: obj1
값 : @5001
   
데이터 영역 주소 5001 5002 5003 5004
데이터 @7103 ~ ? 1 'bbb' 2
객체 @5001의
변수영역
주소 7103 7104 7105 7106
데이터 이름 : a
값 : @5004
이름 : b
값 : @5003
   

obj1의 식별자 주소를 찾는다. 값의 주소이므로 주소로 이동한다. 값의 주소이므로 또 주소로 이동한다.

a의 식별자를 찾는다. 데이터 영역에 2 값이 있는지 찾고 없으면 생성한다.

+. 중첩 객체의 경우 변수 영역이 여러개 생긴다고 보면 된다.

 

가비지 컬렉터

가비지 컬렉터는 런타임 환경에 따라 특정 시점이나 메모리 사용량이 포화 상태에 임박할 때 자동으로 수거 대상들을 수거한다.

수거된 메모리는 다시 새로운 값을 할당할 수 있는 빈 공간이 된다.

참조 카운트가 0인 메모리 주소는 가비지 컬렉터의 수집 대상이 된다.

 

변수 복사 비교

var a = 10
var b = a

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

변수 복사 과정은 기본형 데이터와 참조형 데이터 모두 같은 주소를 바라보게 되는 것은 동일하다.

b = 15
obj2.c = 20

위 코드를 실행하게되면 변수 영역의 값이 기본형은 달라지나 참조형은 달라지지 않는다.

단, 위 코드는 비교예시가 잘못되었다. 위 코드는 기본형은 값을 할당하는거지만, 참조형은 프로퍼티 데이터를 변경하는 것이다.

obj2 = { c: 20, d= 'ddd' }

이렇게 참조형도 데이터 자체를 변경할 경우는 기본형과 같이 변수 영역의 값이 달라진다.

참조형 데이터가 가변값이라고 설명하는 부분은 참조형 데이터 자체를 변경할 경우가 아니라 그 내부의 프로퍼티를 변경할 때만 성립한다.

 

불변 객체

값으로 전달받은 객체에 변경을 가하더라도 원본 객체는 변하지 않아야 하는 경우에 필요하다.

개발자들끼리 불변 객체 사용 합의는 휴먼 에러 등 약속이 깨지기 쉬워 시스템적 제약을 걸어 많이 사용한다.(immutable.js, baobab.js...)

 

얕은 복사와 깊은 복사

얕은 복사는 바로 아래 단계의 값만 복사하는 방법이다.

중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주솟값만 복사한다.

해당 프로퍼티 원본 및 사본 모두 동일한 참조형 데이터 주소를 가리키게 된다. 즉, 사본을 바꾸면 원본도 함께 바뀐다.

var copyObjectDeep = function (target) {
    var result = {}
    for (var prop in target) {
        result[prop] = target[prop]
    }
    return result
}

 

깊은 복사는 내부의 모든 값들을 하나하나 찾아서 복사하는 방법이다.

1. 중첩된 객체의 경우 내부 객체까지 복사하는 함수를 사용하거나,

var copyObjectDeep = function (target) {
    var result = {}
    if (typeof target === 'object' && target !== null) {
    	for (var prop in target) {
            result[prop] = copyObjectDeep(target[prop])
        }
    } else {
    	result = target
    }
    return result
}

2. JSON 문법으로 표현된 문자열로 전환했다가 JSON 객체로 바꾸는 방법이 있다.

var copyObjectViaJSON = function (target) {
    return JSON.parse(JSON.stringify(target))
}

단, JSON 문법을 활용하는 방법은 메서드나 숨겨진 프로퍼티은 __proto__나 getter/setter 등과 같이 JSON으로 변경할 수 없는 프로퍼티들은 모두 무시한다.

 

undefined와 null

undefined는 자바스크립트 엔진이 자동으로 부여하거나 사용자가 직접 할당할 수 있다.

단, 자바스크립트 엔진이 자동으로 부여한 경우와 사용자가 직접 할당한 경우의 동작이 달라 혼란을 일으킬 수 있다.

따라서 값이 없음을 표시하고 싶을때는 undefined가 아닌 null을 활용해야한다.

단, null은 자바스크립트 오류로 typeof null을 하면 object가 표시되기 때문에 비교를 위해서는 null === null 일치 연산자를 활용해야 한다.

반응형

댓글