자바스크립트의 자료형

현재 문서는 편집 검토가 필요합니다.

현재 번역은 완벽하지 않습니다. 한국어로 문서 번역에 동참해주세요.

모든 프로그래밍 언어는 내장 자료형이 있지만, 종종 이러한 내장 자료형은 언어마다 다르다. 이 문서에서는 자바스크립트의 내장 자료형과, 내장 자료형에서 사용할 수 있는 속성들에 대해 알아본다. 이로써 내장 자료형들로 더 복잡한 자료형을 만드는데 사용할 수 있을 것이다. 가능하다면 다른 언어와도 비교해보자.

동적 타이핑

자바스크립트는 느슨한 타입 (loosely typed) 언어, 혹은 동적 (dynamic) 언어이다. 그 말은, 변수의 타입을 미리 선언할 필요가 없다는 뜻이다. 타입은 프로그램이 처리되는 과정에서 자동으로 파악될 것이다. 또한 그 말은 같은 변수에 여러 타입의 값을 넣을 수 있다는 뜻이다.

var foo = 42;    // foo 는 이제 Number 임
var foo = "bar"; // foo 는 이제 String 임
var foo = true;  // foo 는 이제 Boolean 임

데이터 타입

최신 ECMAScript 표준은 다음과 같은 6개의 자료형을  정의한다.

다음 장에서 이 여섯개의 자료형을 사용하는 방법과 자료형을 조합하여 더 복잡한 자료형을 만드는 방법에 대해 알아보자.

기본 타입 (Primitive values)

오브젝트를 제외한 변경 불가능한 값 (immutable value) 이다. 예를 들자면, 특히 C 언어와는 다르게도, 문자열은 불변값 (immutable) 이다. 이런 값을 "primitive values" 라고 일컫는다. 아래의  Strings 장에서 더 자세히 설명할 것이다.

Boolean 타입

Boolean 은 논리적인 요소를 나타내고, truefalse 의 두 가지 값을 가질 수 있다.

Null 타입

Null 타입은 딱 한 가지 값, null 을 가질 수 있다. 더 알아보려면 nullNull 을 보라.

Undefined 타입

값을 할당하지 않은 변수는 undefined 값을 가진다. 더 알아보려면 undefinedUndefined 을 보라.

이 세 가지 타입은 상수이므로, 이것들로 다른 오브젝트를 표현할 수 없다.

Number 타입

ECMAScript 표준에 따르면, 숫자의 자료형은 배정밀도 64비트 형식 IEEE 754 값 (-(253 -1) 와 253 -1 사이의 숫자값) 단 하나만 존재한다. 정수만을 표현하기 위한 특별한 자료형은 없다. 부동 소수점을 표현할 수 있는 것 말고도, Number 타입은 세 가지 의미있는 몇가지 상징적인 값들도 표현할 수 있다. 이 값에는 +무한대, -무한대, and NaN (숫자가 아님)이 있다.

+/-Infinity 보다 크거나 작은지 확인하는 용도로 상수값인 Number.MAX_VALUENumber.MIN_VALUE 을 사용할 수 있다. 또한, ECMAScript 6 부터는 숫자가 배정밀도 부동소수점 숫자인지 확인하는 용도로 Number.isSafeInteger()Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER 을 사용할 수 있다. 이 범위를 넘어서면, 자바스크립트의 숫자는 더 이상 안전하지 않다.

Number 타입의 값 중에는 두 가지 방식으로 표현할 수 있는 유일한 값이 있는데, 0 이다. 0 은 -0 이나 +0 으로 표시할 수 있다. ("0" 은 물론 +0 이다.) 실제로는 이러한 사실은 거의 효력이 없다. 그 예로, +0 === -0true 이다. 하지만 0으로 나누는 경우 그 차이가 눈에 띌 것이다.

> 42 / +0
Infinity
> 42 / -0
-Infinity

숫자가 보통 값만으로 표현되긴 하지만, 자바스크립트는 몇 가지 이진 연산자도 제공한다. 이러한 이진 연산자들은 비트 마스킹(bit masking) 기법으로 한 숫자 안에 여러 Boolean 값을 저장하는데도 쓸 수 있다. 일반적으로 이런 방법은 나쁜 방법이지만, 자바스크립트에서는 (Boolean 값의 배열이나 Boolean 값들을 이름있는 속성들로 가지는 객체 같은) Boolean 덩어리를 나타낼 다른 방법이 없다. 비트 마스킹은 또한 코드를 이해하고, 읽고, 유지보수하는데에 있어서 좀 더 어렵게 만드는 경향이 있다. 하지만 이러한 기법은 local storage 의 저장공간이 부족해서 절약하려고 하거나, 네트워크 상에서 각각의 비트를 전송하는 등의 극단적인 상황 같은 굉장히 제한적인 환경에서 필요할 수도 있다. 그래서 비트 마스킹 기법은 크기를 최대한 줄여야하는 상황에서만 사용을 고려해야 한다.

String 타입

자바스크립트의 String 타입은 텍스트 데이터를 나타내는데 사용한다. 이는 16비트 부호없는 정수 값 요소들의 집합이다. String의 각 요소는 String의 위치를 차지한다. 첫 번째 요소는 0번 인덱스에 있고, 다음 요소는 1번, 그 다음 요소는 2번... 같은 방식이다. String 의 길이는 String이 가지고있는 요소의 갯수이다.

C 같은 언어와는 다르게, 자바스크립트의 문자열은 변경 불가능 (immutable) 하다. 이것은 한 번 문자열이 생성되면, 그 문자열을 수정할 수 없다는걸 의미한다. 그러나 원래 문자열에서 일부가 수정된 다른 문자열을 만드는건 가능하다. 예를 들자면 이렇다.

  • 원래 문자열에서 각각의 글자를 추출하거나 String.substr()을 사용해서 만든 부분 문자열
  • 접합 연산자 (+) 나 String.concat() 으로 두 문자열을 합친 문자열

"문자열의 자료형화"를 조심하라!

문자열을 복잡한 자료형을 표현하는 용도로 쓰는 방법이 꽤나 매력적일 수 있다. 단기적으로 이런 장점들이 있다.

  • 접합 연산자로 손쉽게 복잡한 문자열을 만들 수 있다.
  • 문자열은 디버깅이 쉽다 (화면에 출력한 내용이 문자열 변수에 있는 값과 같다)
  • 문자열은 많은 API 에서 사용하는 공통분모이고 (입력 필드, 로컬 스토리지  값, XMLHttpRequest 요청에서 responseText를 사용할 때 등) 그러다보니 문자열만으로 작업하는게 매혹적일 수 있다.

규칙만 잘 정의해놓는다면, 어떤 자료구조가 되던 문자열로 표시할 수 있다. 그렇다고 해서 이게 좋은 방법이 되는 건 아니다. 예를 들자면, 구분자로 리스트 자료형을 흉내낼 수 있을 것이다 (하지만 자바스크립트의 배열을 사용하는게 더 알맞을 것이다). 불행하게도, 리스트의 요소중에 구분자가 들어있는 요소가 있다면 리스트는 엉망진창이 될 것이다. 물론 탈출 문자 (escape character) 등을 사용하거나 할 수도 있을 것이다. 하지만 이런 것들은 모두 미리 정해놓은 규칙을 필요로 하고, 덕분에 불필요한 관리 부담을 낳는다.

문자열은 텍스트 데이터에만 사용하자. 복잡한 데이터를 나타낼때는, 문자열을 분석해서 적합한 추상화를 선택해 사용하자.

Symbol 타입

Symbol 은 ECMAScript 6 에서 추가되었다. Symbol은 유일하고 변경 불가능한 (immutable) 기본값 (primitive value) 이다. 또한, 객체 속성의 key 값으로도 사용될 수 있다 (아래를 볼 것). 몇몇 프로그래밍 언어에서는 Symbol을 atom 이라고 부른다. 또, C 언어의 이름있는 열거형 (enum) 과도 비슷하다. 좀 더 자세히 알아보려면, 자바스크립트의  SymbolSymbol 객체 래퍼 (wrapper) 를 보라.

객체 (Objects)

컴퓨터 과학에서, 객체는 식별자 (Identifier) 로 참조할 수 있는, 메모리에 있는 값이다.

속성 (Properties)

자바스크립트에서, 객체는 속성들을 담고있는 가방 (collection) 으로 볼 수 있다. 객체 리터럴 문법 (object literal syntax) 으로 제한적으로 몇 가지 속성을 초기화할 수 있고, 그러고 나서 속성들을 추가하거나 제거할 수도 있다. 속성 값은 객체를 포함해 어떠한 자료형도 될 수 있고, 그 덕분에  복잡한 데이터 구조를 형성하는게 가능해진다. 속성은 키 (key) 값으로 식별된다. 키 값은 String 이거나 Symbol 값이다.

두 종류의 객체 속성이 있는데, 이들은 종류에 따라 특성값들을 가질 수 있다. 데이터 (data) 속성과 접근자 (accessor) 속성이 그것이다.

데이터 속성 (Data property)

키에 값을 연결하고, 아래와 같은 특성들 (attribute) 이 있다.

데이터 속성의 특성들
특성 (Attribute) 자료형 설명 기본값
[[Value]] JavaScript 타입 모두 가능 이 속성에 대한 get 접근으로 반환되는 값. undefined
[[Writable]] Boolean false 라면, 이 속성의 [[Value]] 을 바꿀 수 없다. false
[[Enumerable]] Boolean true 라면, 이 속성은 for...in 루프에서 열거될 수 있다. false
[[Configurable]] Boolean false 라면, 이 속성은 제거될 수 없고, [[Value]]와 [[Writable]] 외에는 수정될 수 없다. false

접근자 속성 (Accessor property)

값을 가져오거나 값을 저장하기 위해 키에 하나 혹은 두 개의 접근자 함수 (get, set) 연결짓는다. 아래와 같은 특성이 있다.

접근자 속성
특성 (Attribute) 자료형 설명 기본값
[[Get]] Function 객체 혹은 undefined 이 속성의 값에 접근할 때마다, 인자 목록 없이 함수가 호출되고, 함수의 반환된 값으로 속성값을 가져온다. get 을 볼 것 undefined
[[Set]] Function 객체 혹은 undefined

이 속성의 값이 바뀌려고 할 때마다, 할당된 값을 인자로 함수가 호출된다. set 을 볼 것

undefined
[[Enumerable]] Boolean true 라면, 이 속성은 for...in 루프에서 열거될 수 있다. false
[[Configurable]] Boolean false 라면, 이 속성은 제거될 수 없고, 데이터 속성을 수정할 수 없다. false

"Normal" objects, and functions

자바스크립트 오브젝트는 키와 값의 매핑이다. 키는 문자열이고 값은 다른 어떤 값도 될 수 있다. 오브젝트는 hashmaps을 표현하는데 적합하다. 표준이 아닌 __proto__  슈도 프로퍼티를 사용할 때는 주의하자. 이것을 지원하는 환경에서는 '__proto__'는 오브젝트의 프로토타입을 의미하므로 이 이름을 키로 사용할 수 없다.   속성을 사용할 수 없다. 문자열의 출처가 분명하지 않을 때(입력 필드의 입력값 등)주의가 필요하다. 이런 일이 생길 수도 있다. 이 때는  StringMap abstraction 같은 대안을 사용해보자.

함수는 일반 오브젝트에서 호출 가능한 특성을 추가한 오브젝트이다.

Arrays

배열(Arrays) 는 정수키를 가지는 일련의 값들을 표현하기 위한 오브젝트이다. 배열 오브젝트에는 길이를 나타내는 'length'란 속성도 있다. 배열은 Array.prototype을 상속받으므로 배열을 다룰 때 편한 indexOf (배열에서 값 검색)와 push (새로운 값 추가) 같은 함수를 사용할 수 있다. 배열은 리스트나 집합을 표현하는데 적합하다.

Dates

시간을 나타내려면 Date utility를 사용하자. 최고의 선택이다.

WeakMaps, Maps, Sets

표준이 아니지만 ECMAScript 6에서 표준이 될 것 같다.

이 자료형들에서는 키가 문자열 뿐만 아니라 오브젝트도 될 수 있다. Set은 오브젝트의 집합을 나타내는 반면에 WeakMaps와 Maps는 오브젝트에 값을 연관시킬 수 있다. Map과 WeakMap의 차이는 전자는 오브젝트 키를 열거할 수 있다는 것이다. 이것은 가비지 콜렉션에서 이점을 준다.

ECMAScript 5를 이용해서 Map과 Set을 구현할 수 있을 것이다. 그러나 오브젝트는 크기 비교가 안된다는 점 때문에(예를들어 어떤 오브젝트는 다른 오브젝트보다 '작다'라고 할 수 없다) look-up에 소요되는 시간이 선형 시간이지 않을 것이다. 네이티브 구현은(WeakMaps를 포함해서) look-up 시간이 거의 로그 시간에서 상수 시간이다.

DOM 노드에 데이터를 지정하기 위해서 직접 속성을 지정할 수도 있지만 data-* 속성을 사용할 수도 있다. 여기에는 다른 스크립트도 모두 그 속성에 접근할 수 있다는 나쁜 점이 있다. Map과 WeakMap은 오브젝트만 사용할 수 있는 개인 데이터를 쉽게 만들 수 있게 해준다.

TypedArrays

표준이 아니지만 ECMAScript 6에서 표준이 될 것 같다.

더 보기

문서 태그 및 공헌자

최종 변경: Ch_Softblow,
사이드바 숨기기