데이터 타입(Data Type)

Seunghyo Ku·2021년 3월 12일
0

JavaScript

목록 보기
2/3
post-thumbnail

해당 시리즈는 코어 자바스크립트(정재남 저)를 읽고 요약한 내용입니다.

  • 1장 - Data Type (현재 글)

메모리와 데이터

자바스크립트는 숫자의 경우 정수형/부동소수형을 구분하지 않고 64비트(8 바이트)의 공간을 확보합니다.

데이터 타입의 종류

  • 기본형(원시형, primitive type): 할당이나 연산시 값이 담긴 주소값을 복제한다.Number, String, Boolean, null, undefined, Symbol
  • 참조형(reference type): 할당이나 연산시 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주솟값을 복제한다. (=참조한다.)Array, Function, Date, RegExp, Map(WeakMap), Set(WeakSet)

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

메모리와 데이터

모든 데이터는 바이트 단위의 식별자, 즉 메모리 주솟값(memory address)를 통해 서로 구분하고 연결됩니다.

식별자와 변수

  • 변수(variable): 변할 수 있는 무언가 (데이터)
  • 식별자(identifier): 변수명

변수 선언과 데이터 할당

변수 선언

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

데이터 할당

데이터 변환을 자유롭게 하고, 메모리를 효율적으로 관리하기 위해 변수 영역에 값을 직접 넣는 것이 아니고 데이터 영역에 따로 저장한 뒤 변수가 데이터 영역의 주소를 가리키게 합니다.

이것이 왜 효율적일까요?

  1. 중복 데이터에 대한 처리 효율이 높아집니다.
  2. 미리 확보된 공간보다 더 큰 데이터 변환이 이루어딪다면 이루어질 작업을 막을 수 있습니다.

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

불변값 (mutable)

문자열 값도 한 번 만든 값을 바꿀 수 없고, 숫자 값도 다른 값으로 변경할 수 없습니다. 이처럼 불변값은 변경은 새로 만드는 동작을 통해서만 이뤄지는 것입니다. 모든 기본형 데이터는 불변값입니다.

가변값 (immutable)

대부분의 참조형 데이터는 가변값입니다. 참조형 데이터가 기본형 데이터와 다른 것은 객체의 변수(프로퍼티) 영역이 별도로 존재한다는 것에서 다릅니다.

var Seunghyo = {
  name: '구승효',
  nation: '감자국',
  hobby: ['coding', 'game'],
};

obj.hobby = 'sleeping';

이 경우, nation의 값이 '서울'을 가리키게 되면서 객체 자체가 아닌, hobby 내부의 값만 바뀌기 때문에 가변하다(=불변하지 않다)고 할 수 있습니다.

이처럼 값이 변경 되어 참조 카운터(자신의 주소를 참조하는 변수의 개수)가 0이 되는 경우 (위의 예제에서는 ['coding', 'game'] 부분을 의미합니다.) , 가비지 컬렉터(garbage collector)에 의해 수거됩니다.

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

변수 복사 비교

참조형 데이터 자체를 변경할 경우가 아닌, 내부의 프로퍼티를 변경할 때만 성립합니다.

참조형 데이터(예: 객체)에도 새 객체를 할당하게 되면 값을 직접 변경하게 됩니다.

불변 객체

불변 객체를 만드는 간단한 방법

불변 객체(immutable object)는 원본 객체가 변하면 안 될 때 사용됩니다. 내부 프로퍼티를 변경할 필요가 있을 때마다 새로운 객체를 만들어 재할당하거나 자동으로 새 객체를 만들게 됩니다.

얕은 복사와 깊은 복사

  • 얕은 복사(shallow copy): 바로 아래 단계의 값만 복사 -> 주솟값만 복사 (사본을 바꾸면 원본도 바뀌게 된다.)
  • 깊은 복사(deep copy): 내부의 모든 값들을 하나하나 찾아서 전부 복사

깊은 복사를 하고 싶을 때는, 참조형 데이터의 경우 내부의 프로퍼티들을 복사해야 됩니다.

hasOwnProperty 메서드를 이용해 프로토타입 체이닝을 통해 상속된 프로퍼티를 복사하지 않게끔 할 수 있습니다.

  • 프로토타입 체이닝: 객체에 원하는 값이 없을 경우, 객체 생성 시 함께 생성되는 프로토타입으로 올라가 값을 찾습니다.
  • hasOwnProperty: (MDN Docs) 해당 프로퍼티가 있는지 true/false로 리턴합니다. 이를 이용해 상속된 프로퍼티를 복사하지 않게끔 할 수 있습니다.

ES5 문법인 getter/setter를 복사하는 방법은 ES6의 getOwnPropertyDescriptor 또는 ES2017의 getOwnPropertyDescriptors 밖에 없습니다.

  • Object.getOwnPropertyDescriptor : 객체에 대한 descriptor 반환(configurable/enumerable/value/writable/get/set) → 해당 값들을 정의할 때 Object.defineProperty로 할 수 있습니다.
    • configurable: 유형이 바뀔 수 있는 경우
    • getter/setter가 정의되지 않은 경우 get/set은 undefined
    • writable: 값이 변할 수 있는 경우
    • enumerable: 열거로 나타나는 경우

또는 객체를 JSON의 문자열로 전환했다가 다시 JSON 객체로 바꾸는 방법이 있습니다. httpRequest 등의 통신에서 사용할 때 (순수한 정보만 다룰 때) 유용하게 사용될 수 있습니다. 다만, 이 방법의 경우 함수나 숨겨진 프로퍼티(__proto__)의 경우 JSON으로 변경할 수 없는 프로퍼티는 무시하게 됩니다.

undefined와 null

  • undefined: 사용자가 값을 지정하지 않았을 때
    1. 값을 대입하지 않은 변수
    2. 객체 내부의 존재하지 않는 프로퍼티
    3. return 문이 없거나 호출되지 않는 함수의 실행 결과
    • 만약 없는 값이 아니라 undefined를 명시한다면 값이 있는 것으로 간주하여 배열 순회 등의 동작이 발생한다.
  • null: 비어있음을 명시적으로 나타내고 싶을 때
    • typeof null : object 이기 때문에 변수 === null 과 같은 형식으로 사용해주어야 합니다.
profile
꼬꼬마 개발자 구승효입니다!

0개의 댓글