--- title: 자바스크립트의 자료형 slug: Web/JavaScript/Data_structures translation_of: Web/JavaScript/Data_structures ---
모든 프로그래밍 언어는 내장 자료형이 있지만, 종종 이러한 내장 자료형은 언어마다 다르다. 이 문서에서는 자바스크립트의 내장 자료형과, 내장 자료형에서 사용할 수 있는 속성들에 대해 알아본다. 이로써 내장 자료형들로 더 복잡한 자료형을 만드는데 사용할 수 있을 것이다. 가능하다면 다른 언어와도 비교해보자.
자바스크립트는 느슨한 타입 (loosely typed) 언어, 혹은 동적 (dynamic) 언어이다. 그 말은, 변수의 타입을 미리 선언할 필요가 없다는 뜻이다. 타입은 프로그램이 처리되는 과정에서 자동으로 파악될 것이다. 또한 그 말은 같은 변수에 여러 타입의 값을 넣을 수 있다는 뜻이다.
var foo = 42; // foo 는 이제 Number 임 var foo = "bar"; // foo 는 이제 String 임 var foo = true; // foo 는 이제 Boolean 임
최신 ECMAScript 표준은 다음과 같은 7개의 자료형을 정의한다.
다음 장에서 이 여섯개의 자료형을 사용하는 방법과 자료형을 조합하여 더 복잡한 자료형을 만드는 방법에 대해 알아보자.
오브젝트를 제외한 모든 값은 변경 불가능한 값 (immutable value) 이다. 예를 들자면, 특히 C 언어와는 다르게도, 문자열은 불변값 (immutable) 이다. 이런 값을 "primitive values" 라고 일컫는다. 아래의 {{ anch("Strings") }} 장에서 더 자세히 설명할 것이다.
Boolean 은 논리적인 요소를 나타내고, true
와 false
의 두 가지 값을 가질 수 있다.
Null 타입은 딱 한 가지 값, null
을 가질 수 있다. 더 알아보려면 {{jsxref("null")}} 와 {{Glossary("Null")}} 을 보라.
값을 할당하지 않은 변수는 undefined
값을 가진다. 더 알아보려면 {{jsxref("undefined")}} 와 {{Glossary("Undefined")}} 을 보라.
ECMAScript 표준에 따르면, 숫자의 자료형은 배정밀도 64비트 형식 IEEE 754 값 (-(253 -1) 와 253 -1 사이의 숫자값) 단 하나만 존재한다. 정수만을 표현하기 위한 특별한 자료형은 없다. 부동 소수점을 표현할 수 있는 것 말고도, Number 타입은 세 가지 의미있는 몇가지 상징적인 값들도 표현할 수 있다. 이 값에는 +무한대
, -무한대
, and NaN
(숫자가 아님)이 있다.
+/-Infinity
보다 크거나 작은지 확인하는 용도로 상수값인 {{jsxref("Number.MAX_VALUE")}} 나 {{jsxref("Number.MIN_VALUE")}} 을 사용할 수 있다. 또한, ECMAScript 6 부터는 숫자가 배정밀도 부동소수점 숫자인지 확인하는 용도로 {{jsxref("Number.isSafeInteger()")}} 과 {{jsxref("Number.MAX_SAFE_INTEGER")}}, {{jsxref("Number.MIN_SAFE_INTEGER")}} 을 사용할 수 있다. 이 범위를 넘어서면, 자바스크립트의 숫자는 더 이상 안전하지 않다.
Number 타입의 값 중에는 두 가지 방식으로 표현할 수 있는 유일한 값이 있는데, 0 이다. 0 은 -0 이나 +0 으로 표시할 수 있다. ("0" 은 물론 +0 이다.) 실제로는 이러한 사실은 거의 효력이 없다. 그 예로, +0 === -0
은 true
이다. 하지만 0으로 나누는 경우 그 차이가 눈에 띌 것이다.
> 42 / +0
Infinity
> 42 / -0
-Infinity
숫자가 보통 값만으로 표현되긴 하지만, 자바스크립트는 몇 가지 이진 연산자도 제공한다. 이러한 이진 연산자들은 비트 마스킹(bit masking) 기법으로 한 숫자 안에 여러 Boolean 값을 저장하는데도 쓸 수 있다. 일반적으로 이런 방법은 나쁜 방법이지만, 자바스크립트에서는 (Boolean 값의 배열이나 Boolean 값들을 이름있는 속성들로 가지는 객체 같은) Boolean 덩어리를 나타낼 다른 방법이 없다. 비트 마스킹은 또한 코드를 이해하고, 읽고, 유지보수하는데에 있어서 좀 더 어렵게 만드는 경향이 있다. 하지만 이러한 기법은 local storage 의 저장공간이 부족해서 절약하려고 하거나, 네트워크 상에서 각각의 비트를 전송하는 등의 극단적인 상황 같은 굉장히 제한적인 환경에서 필요할 수도 있다. 그래서 비트 마스킹 기법은 크기를 최대한 줄여야하는 상황에서만 사용을 고려해야 한다.
자바스크립트의 {{jsxref("Global_Objects/String", "String")}} 타입은 텍스트 데이터를 나타내는데 사용한다. 이는 16비트 부호없는 정수 값 요소들의 집합이다. String의 각 요소는 String의 위치를 차지한다. 첫 번째 요소는 0번 인덱스에 있고, 다음 요소는 1번, 그 다음 요소는 2번... 같은 방식이다. String 의 길이는 String이 가지고있는 요소의 갯수이다.
C 같은 언어와는 다르게, 자바스크립트의 문자열은 변경 불가능 (immutable) 하다. 이것은 한 번 문자열이 생성되면, 그 문자열을 수정할 수 없다는걸 의미한다. 그러나 원래 문자열에서 일부가 수정된 다른 문자열을 만드는건 가능하다. 예를 들자면 이렇다.
String.substr()
을 사용해서 만든 부분 문자열+
) 나 String.concat()
으로 두 문자열을 합친 문자열문자열을 복잡한 자료형을 표현하는 용도로 쓰는 방법이 꽤나 매력적일 수 있다. 단기적으로 이런 장점들이 있다.
responseText
를 사용할 때 등) 그러다보니 문자열만으로 작업하는게 매혹적일 수 있다.규칙만 잘 정의해놓는다면, 어떤 자료구조가 되던 문자열로 표시할 수 있다. 그렇다고 해서 이게 좋은 방법이 되는 건 아니다. 예를 들자면, 구분자로 리스트 자료형을 흉내낼 수 있을 것이다 (하지만 자바스크립트의 배열을 사용하는게 더 알맞을 것이다). 불행하게도, 리스트의 요소중에 구분자가 들어있는 요소가 있다면 리스트는 엉망진창이 될 것이다. 물론 탈출 문자 (escape character) 등을 사용하거나 할 수도 있을 것이다. 하지만 이런 것들은 모두 미리 정해놓은 규칙을 필요로 하고, 덕분에 불필요한 관리 부담을 낳는다.
문자열은 텍스트 데이터에만 사용하자. 복잡한 데이터를 나타낼때는, 문자열을 분석해서 적합한 추상화를 선택해 사용하자.
Symbol 은 ECMAScript 6 에서 추가되었다. Symbol은 유일하고 변경 불가능한 (immutable) 기본값 (primitive value) 이다. 또한, 객체 속성의 key 값으로도 사용될 수 있다 (아래를 볼 것). 몇몇 프로그래밍 언어에서는 Symbol을 atom 이라고 부른다. 또, C 언어의 이름있는 열거형 (enum) 과도 비슷하다. 좀 더 자세히 알아보려면, 자바스크립트의 {{Glossary("Symbol")}} 와 {{jsxref("Symbol")}} 객체 래퍼 (wrapper) 를 보라.
컴퓨터 과학에서, 객체는 {{Glossary("Identifier", "식별자 (Identifier)")}} 로 참조할 수 있는, 메모리에 있는 값이다.
자바스크립트에서, 객체는 속성들을 담고있는 가방 (collection) 으로 볼 수 있다. 객체 리터럴 문법 (object literal syntax) 으로 제한적으로 몇 가지 속성을 초기화할 수 있고, 그러고 나서 속성들을 추가하거나 제거할 수도 있다. 속성 값은 객체를 포함해 어떠한 자료형도 될 수 있고, 그 덕분에 복잡한 데이터 구조를 형성하는게 가능해진다. 속성은 키 (key) 값으로 식별된다. 키 값은 String 이거나 Symbol 값이다.
두 종류의 객체 속성이 있는데, 이들은 종류에 따라 특성값들을 가질 수 있다. 데이터 (data) 속성과 접근자 (accessor) 속성이 그것이다.
키에 값을 연결하고, 아래와 같은 특성들 (attribute) 이 있다.
특성 (Attribute) | 자료형 | 설명 | 기본값 |
---|---|---|---|
[[Value]] | JavaScript 타입 모두 가능 | 이 속성에 대한 get 접근으로 반환되는 값. | undefined |
[[Writable]] | Boolean | false 라면, 이 속성의 [[Value]] 을 바꿀 수 없다. |
false |
[[Enumerable]] | Boolean | true 라면, 이 속성은 for...in 루프에서 열거될 수 있다. |
false |
[[Configurable]] | Boolean | false 라면, 이 속성은 제거될 수 없고, [[Value]]와 [[Writable]] 외에는 수정될 수 없다. |
false |
값을 가져오거나 값을 저장하기 위해 키에 하나 혹은 두 개의 접근자 함수 (get, set) 연결짓는다. 아래와 같은 특성이 있다.
특성 (Attribute) | 자료형 | 설명 | 기본값 |
---|---|---|---|
[[Get]] | Function 객체 혹은 undefined | 이 속성의 값에 접근할 때마다, 인자 목록 없이 함수가 호출되고, 함수의 반환된 값으로 속성값을 가져온다. get 을 볼 것 |
undefined |
[[Set]] | Function 객체 혹은 undefined |
이 속성의 값이 바뀌려고 할 때마다, 할당된 값을 인자로 함수가 호출된다. |
undefined |
[[Enumerable]] | Boolean | true 라면, 이 속성은 for...in 루프에서 열거될 수 있다. |
false |
[[Configurable]] | Boolean | false 라면, 이 속성은 제거될 수 없고, 데이터 속성을 수정할 수 없다. |
false |
자바스크립트 오브젝트는 키와 값의 매핑이다. 키는 문자열이고 값은 다른 어떤 값도 될 수 있다. 오브젝트는 hashmaps을 표현하는데 적합하다. 표준이 아닌 __proto__ 슈도 프로퍼티를 사용할 때는 주의하자. 이것을 지원하는 환경에서는 '__proto__'는 오브젝트의 프로토타입을 의미하므로 이 이름을 키로 사용할 수 없다. 속성을 사용할 수 없다. 문자열의 출처가 분명하지 않을 때(입력 필드의 입력값 등)
주의가 필요하다. 이런 일이 생길 수도 있다. 이 때는 StringMap abstraction 같은 대안을 사용해보자.함수는 일반 오브젝트에서 호출 가능한 특성을 추가한 오브젝트이다.
시간을 나타내려면 Date utility를 사용하자. 최고의 선택이다.
배열(Arrays) 는 정수키를 가지는 일련의 값들을 표현하기 위한 오브젝트이다. 배열 오브젝트에는 길이를 나타내는 'length'란 속성도 있다. 배열은 Array.prototype을 상속받으므로 배열을 다룰 때 편한 indexOf (배열에서 값 검색)와 push (새로운 값 추가) 같은 함수를 사용할 수 있다. 배열은 리스트나 집합을 표현하는데 적합하다.
표준이 아니지만 ECMAScript 6에서 표준이 될 것 같다.
이 자료형들에서는 키가 문자열 뿐만 아니라 오브젝트도 될 수 있다. Set은 오브젝트의 집합을 나타내는 반면에 WeakMaps와 Maps는 오브젝트에 값을 연관시킬 수 있다. Map과 WeakMap의 차이는 전자는 오브젝트 키를 열거할 수 있다는 것이다. 이것은 가비지 콜렉션에서 이점을 준다.
ECMAScript 5를 이용해서 Map과 Set을 구현할 수 있을 것이다. 그러나 오브젝트는 크기 비교가 안된다는 점 때문에(예를들어 어떤 오브젝트는 다른 오브젝트보다 '작다'라고 할 수 없다) look-up에 소요되는 시간이 선형 시간이지 않을 것이다. 네이티브 구현은(WeakMaps를 포함해서) look-up 시간이 거의 로그 시간에서 상수 시간이다.
DOM 노드에 데이터를 지정하기 위해서 직접 속성을 지정할 수도 있지만 data-* 속성을 사용할 수도 있다. 여기에는 다른 스크립트도 모두 그 속성에 접근할 수 있다는 나쁜 점이 있다. Map과 WeakMap은 오브젝트만 사용할 수 있는 개인 데이터를 쉽게 만들 수 있게 해준다.
표준이 아니지만 ECMAScript 6에서 표준이 될 것 같다.