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

YEN·2022년 7월 19일

JavaScript

목록 보기
5/7
post-thumbnail

1. 데이터 타입

  • 자바스크립트의 데이터 타입에는 크게 두 가지로 "기본형 Primitive type / 참조형 Reference type"이 있다.

어떤 기준으로 기본형과 참조형을 구분하는 것인가?

기본형은 불변성을 띈다.
but, 기본형인 숫자 10을 담은 변수 a에 다시 숫자 20을 담으면 a의 값은 문제 없이 20으로 변한다.

그렇다면 '변하지 않는다'라는 것은 어떤 의미인 것인가?
-> 불변성을 이해하기 위해선 '식별자'와 '변수'의 개념을 구분할 수 있어야 한다.


2. 데이터 타입에 관한 배경지식

1) 메모리와 데이터

  • 컴퓨터는 모든 데이터를 0 또는 1로 바꿔 기억하는데 이를 표현할 수 있는 하나의 메모리 조각을 비트라고 한다.
    즉, 메모리는 매우 많은 비트들로 구성되어 있는데, 각 비트는 고유한 식별자를 통해 위치를 확인할 수 있다.

    but, 비트 단위로 위치를 확인하는 것은 비효율적이므로 매우 많은 비트를 한 단위로 묶는 편이 낫다.
    -> '바이트'라는 단위가 생겼다.

  • 1바이트 = 8개의 비트

  • 각 비트는 고유한 식별자를 지니므로 바이트 또한 비트의 식별자로 위치를 파악할 수 있다.

모든 데이터는 바이트 단위의 식별자, 더 정확하게 메모리 주솟값을 통해 서로 구분하고 연결할 수 있다.

2) 식별자와 변수

  • 변수: 변할 수 있는 데이터

  • 식별자: 어떤 데이터를 식별하는 데 사용하는 이름, 즉 변수명


3. 변수 선언과 데이터 할당

1) 변수 선언과 할당

var a;
a = 'abc';

var a = 'abc';

변수: 변경 가능한 데이터가 담길 수 있는 공간 또는 그릇


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

1) 불변값

  • 변수와 상수를 구분하는 성질은 '변경 가능성'이다.
    -> 이 변경 가능성의 대상은 변수 영역 메모리이다.
    한 번 데이터 할당이 이루어진 변수 공간에 다른 데이터를 재할당할 수 있는지의 여부가 관건이다.

  • 불변값과 상수를 같은 개념으로 오해하기 쉽다.
    그러나 이 둘은 명확히 구분해야 한다.
    -> 불변성의 여부를 구분할 때는 변경 가능성의 데이터 영역 메모리로 구분한다.

기본형 데이터인 숫자, 문자열, boolean, null, undefined, Symbol은 모두 불변값이다.

var a = 'abc';
a = a + 'def';

변수 a에 문자열 'abc'를 할당하고 'def'를 추가하면 기존의 'abc'가 'abcdef'로 바뀌는 것이 아니라 새로운 문자열 'abcdef'를 만들어 그 주소를 변수 a에 저장한다.

따라서 'abc'와 'abcdef'는 완전히 별개의 데이터이다.

불변값은 한번 만들어진 값은 변경할 수 없다.

2) 가변값

기본형 데이터는 모두 불변값이라고 하였는데 그렇다면 참조형 데이터는 모두 가변값일까?
-> 기본적인 성질은 가변값인 경우가 많지만 설정에 따라 변경 불가인 경우, 불변값인 경우도 있다.

참조형 데이터는 기본형 데이터과 다르게 '객체의 변수 (프로퍼티) 영역'이 별도로 존재한다는 것이다.

객체가 별도로 할애한 영역은 변수 영역일 뿐이고 데이터 영역은 기존의 메모리 공간을 그대로 활용하고 있다.
데이터 영역에 저장된 값은 모두 불변값이지만, 변수에는 다른 값을 대입할 수 있다.
이 부분으로 흔히 참조형 데이터는 가변값이다라고 한다.

ex) 참조형 데이터의 프로퍼티 재할당

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

변수 obj1은 새로운 객체가 만들어진 것이 아니라 기존의 객체 내부의 값만 바뀐 것이다.

ex) 중첩된 참조형 데이터의 프로퍼티 할당
-> 참조형 데이터의 프로퍼티의 다시 참조형 데이터를 할당하는 경우 (중첩 객체)

var obj = {
	x: 5,
    arr: [5, 6, 7]
};
obj.arr = 'str';

참조형 데이터의 '가변'은 데이터 자체가 아닌 내부 프로퍼티를 변경할 때만 성립한다.
-> 데이터 자체를 변경하고자 하면 (새로운 데이터를 할당하고자 하면) 기본형 데이터와 같이 기존 데이터는 변하지 않는다.


5. undefined과 null

자바스크립트에는 '없음'을 나타내는 값 두 가지 undefined과 null가 있다.

1) undefined

사용자가 명시적으로 지정할 수 있지만 값이 존재하지 않을 때 자바스크립트 엔진이 자동으로 부여하는 경우가 있다.
자바스크립트 엔진은 사용자가 어떤 값을 지정할 것이라고 예상되는 상황임에도 실제로 그렇게 하지 않았을 때 undefined를 반환한다.

  • 값이 대입하지 않은 변수
    즉, 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때

  • 객체 내부의 존재하지 않는 프로퍼티에 접근하려고 할 때

  • return 문이 없거나 호출되지 않는 함수의 실행 결과

ex) 자동으로 undefined를 부여하는 경우

var a;
console.log(a);  //undefined. 값을 대입하지 않은 변수에 접근

var obj = {a:1};
console.log(obj.a);  //1
console.log(obj.b);  //존재하지 않는 프로퍼티에 접근
console.log(b);  //undefined

var func = function() {};
var c = func();  //return 값이 없음
console.log(c);  //undefined

ex) undefined와 배열

var arr1 = [];
arr1.length = 3;
console.log(arr1);  //[empty  x 3]

var arr2 = new Array(3);
console.log(arr2);  //[empty  x 3]

var arr3 = [undefined, undefined, undefined];
console.log(arr3);  //[undefined, undefined, undefined]

빈 배열 arr1을 만들고 배열의 크기를 3으로 하니 [empty x 3]가 출력되었다.
-> 이는 배열에 3개의 빈 요소를 확보하였지만 확보된 각 요소에는 어떤 값도 (undefined 포함)도 할당되어 있지 않음을 의미한다.

new 연산자와 함께 Array 생성자 함수를 호출하여 배열 arr2를 생성하였고, 배열의 크기를 3으로 지정하였는데 [empty x 3]로 앞의 결과와 같은 결과가 출력되었다.

배열 arr3에는 각 요소에 undefined를 부여하였더니 이번에는 앞의 두 결과와 달리 [undefined, undefined, undefined]가 출력되었다.

즉, '비어있는 요소'와 'undefined를 할당한 요소'는 출력 결과부터 다르다.

ex) 빈 요소와 배열의 순회

var arr1 = [undefined, 1];
var arr2 = [];
arr2[1] = 1;

arr1.forEach(function (v, i) {console.log(v,i)});  //undefined 0 / 1 1
arr2.forEach(function(v, i) {console.log(v, i)});  //1 1

arr1.map(function(v, i) {return v + i});  //[Nan, 2]
arr2.map(function(v, i) {return v + i});  //[empty, 2]

arr1.filter(function(v) {return !v});  //[undefined]
arr2.filter(function(v) {return !v});  //[]

arr1.reduce(function(p, c, i) {return p + c + i});  //undefined011
arr2.reduce(function(p, c, i) {return p + c + i});  //11

arr1은 undefined와 1을 직접 할당한 반면 arr2는 빈 배열의 인덱스 1에 값 1을 할당하였다.
이 두 배열은 배열의 각 요소를 순회하는 것을 기본으로 추가적인 기능을 수행하는 메서드들 (forEach, map, filter, reduce) 등 에서 서로 다른 결과를 보였다.

사용자가 직접 undefined를 할당한 arr1에서는 배열의 모든 요소를 순회하여 결과를 출력하였다.
arr2에서는 각 메서드들이 비어 있는 요소에 대해서는 어떠한 처리 없이 건너뛰었음을 알 수 있다.

  • 사용자가 명시적으로 undefined를 부여한 경우

    -> 순회의 대상이 될 수 있다.

  • 비어있는 요소에 접근하려 할 때 반환되는 undefined의 경우

    -> 문자 그대로 값이 없음을 나타낸다.

2) null

'비어있음'의 의미로 undefined를 굳이 할당하지 않고 null을 이용하면 된다.

ex) undefined와 null의 비교

var a = null;
console.log(typeof a);  //object

console.log(a == undefined);  //true
console.log(a == null);  //true

console.log(a === undefined);  //false
console.log(a === null);  //true

동등 연산자 ==로 비교할 경우
-> 어떤 변수가 실제로 null인지 아니면 undefined인지는 동등 연산자로 비교 불가


6. 정리

  • 변수: 변경 가능한 데이터를 담을 수 있는 공간
    식별자: 그 변수의 이름

  • undefined: 어떤 변수에 값이 존재하지 않을 경우
    null: 사용자가 명시적으로 없음을 표현하기 위해 대입한 경우

0개의 댓글