diff options
Diffstat (limited to 'files/ko/web/javascript/data_structures/index.md')
-rw-r--r-- | files/ko/web/javascript/data_structures/index.md | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/files/ko/web/javascript/data_structures/index.md b/files/ko/web/javascript/data_structures/index.md new file mode 100644 index 0000000000..14967ae250 --- /dev/null +++ b/files/ko/web/javascript/data_structures/index.md @@ -0,0 +1,221 @@ +--- +title: 자바스크립트의 자료형 +slug: Web/JavaScript/Data_structures +translation_of: Web/JavaScript/Data_structures +--- +<div>{{jsSidebar("More")}}</div> + +<p>모든 프로그래밍 언어는 내장 자료형이 있지만, 종종 이러한 내장 자료형은 언어마다 다르다. 이 문서에서는 자바스크립트의 내장 자료형과, 내장 자료형에서 사용할 수 있는 속성들에 대해 알아본다. 이로써 내장 자료형들로 더 복잡한 자료형을 만드는데 사용할 수 있을 것이다. 가능하다면 다른 언어와도 비교해보자.</p> + +<h2 id="동적_타이핑">동적 타이핑</h2> + +<p>자바스크립트는 <em>느슨한 타입 (loosely typed)</em> 언어, 혹은 <em>동적 (dynamic)</em> 언어이다. 그 말은, 변수의 타입을 미리 선언할 필요가 없다는 뜻이다. 타입은 프로그램이 처리되는 과정에서 자동으로 파악될 것이다. 또한 그 말은 같은 변수에 여러 타입의 값을 넣을 수 있다는 뜻이다.</p> + +<pre class="brush: js notranslate">var foo = 42; // foo 는 이제 Number 임 +var foo = "bar"; // foo 는 이제 String 임 +var foo = true; // foo 는 이제 Boolean 임 +</pre> + +<h2 id="데이터_타입">데이터 타입</h2> + +<p>최신 ECMAScript 표준은 다음과 같은 7개의 자료형을 정의한다.</p> + +<ul> + <li>{{Glossary("Primitive", "기본 자료형 (Primitive)")}} 인 여섯가지 데이터 타입 + <ul> + <li>{{Glossary("Boolean")}}</li> + <li>{{Glossary("Null")}}</li> + <li>{{Glossary("Undefined")}}</li> + <li>{{Glossary("Number")}}</li> + <li>{{Glossary("String")}}</li> + <li>{{Glossary("Symbol")}} (ECMAScript 6 에 추가됨)</li> + </ul> + </li> + <li>별도로 {{Glossary("Object")}} 도 있음</li> +</ul> + +<p>다음 장에서 이 여섯개의 자료형을 사용하는 방법과 자료형을 조합하여 더 복잡한 자료형을 만드는 방법에 대해 알아보자.</p> + +<h2 id="기본_타입_Primitive_value">기본 타입 (Primitive value)</h2> + +<p>오브젝트를 제외한 모든 값은 변경 불가능한 값 (immutable value) 이다. 예를 들자면, 특히 C 언어와는 다르게도, 문자열은 불변값 (immutable) 이다. 이런 값을 "primitive values" 라고 일컫는다. 아래의 {{ anch("Strings") }} 장에서 더 자세히 설명할 것이다.</p> + +<h3 id="Boolean_타입">Boolean 타입</h3> + +<p>Boolean 은 논리적인 요소를 나타내고, <code>true</code> 와 <code>false</code> 의 두 가지 값을 가질 수 있다.</p> + +<h3 id="Null_타입">Null 타입</h3> + +<p>Null 타입은 딱 한 가지 값, <code>null</code> 을 가질 수 있다. 더 알아보려면 {{jsxref("null")}} 와 {{Glossary("Null")}} 을 보라.</p> + +<h3 id="Undefined_타입">Undefined 타입</h3> + +<p>값을 할당하지 않은 변수는 <code>undefined</code> 값을 가진다. 더 알아보려면 {{jsxref("undefined")}} 와 {{Glossary("Undefined")}} 을 보라.</p> + +<h3 id="Number_타입">Number 타입</h3> + +<p>ECMAScript 표준에 따르면, 숫자의 자료형은 <a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format">배정밀도 64비트 형식 IEEE 754 값</a> (-(2<sup>53</sup> -1) 와 2<sup>53</sup> -1 사이의 숫자값) 단 하나만 존재한다. <strong>정수만을 표현하기 위한 특별한 자료형은 없다.</strong> 부동 소수점을 표현할 수 있는 것 말고도, Number 타입은 세 가지 의미있는 몇가지 상징적인 값들도 표현할 수 있다. 이 값에는 <code>+무한대</code>, <code>-무한대</code>, and <code><a href="/ko/docs/Web/JavaScript/Reference/Global_Objects/NaN">NaN</a></code> (숫자가 아님)이 있다.</p> + +<p><code>+/-Infinity</code> 보다 크거나 작은지 확인하는 용도로 상수값인 {{jsxref("Number.MAX_VALUE")}} 나 {{jsxref("Number.MIN_VALUE")}} 을 사용할 수 있다. 또한, ECMAScript 6 부터는 숫자가 배정밀도 부동소수점 숫자인지 확인하는 용도로 {{jsxref("Number.isSafeInteger()")}} 과 {{jsxref("Number.MAX_SAFE_INTEGER")}}, {{jsxref("Number.MIN_SAFE_INTEGER")}} 을 사용할 수 있다. 이 범위를 넘어서면, 자바스크립트의 숫자는 더 이상 안전하지 않다.</p> + +<p>Number 타입의 값 중에는 두 가지 방식으로 표현할 수 있는 유일한 값이 있는데, 0 이다. 0 은 -0 이나 +0 으로 표시할 수 있다. ("0" 은 물론 +0 이다.) 실제로는 이러한 사실은 거의 효력이 없다. 그 예로, <code>+0 === -0</code> 은 <code>true</code> 이다. 하지만 0으로 나누는 경우 그 차이가 눈에 띌 것이다.</p> + +<pre class="brush: js language-js notranslate"><code class="language-js"><span class="operator token">></span> <span class="number token">42</span> <span class="operator token">/</span> <span class="operator token">+</span><span class="number token">0</span> +<span class="number token">Infinity</span> +<span class="operator token">></span> <span class="number token">42</span> <span class="operator token">/</span> <span class="operator token">-</span><span class="number token">0</span> +<span class="operator token">-</span><span class="number token">Infinity</span></code></pre> + +<p>숫자가 보통 값만으로 표현되긴 하지만, 자바스크립트는 <a href="/en/JavaScript/Reference/Operators/Bitwise_Operators" title="en/JavaScript/Reference/Operators/Bitwise_Operators">몇 가지 이진 연산자</a>도 제공한다. 이러한 이진 연산자들은 <a class="external" href="http://en.wikipedia.org/wiki/Mask_%28computing%29">비트 마스킹(bit masking)</a> 기법으로 한 숫자 안에 여러 Boolean 값을 저장하는데도 쓸 수 있다. 일반적으로 이런 방법은 나쁜 방법이지만, 자바스크립트에서는 (Boolean 값의 배열이나 Boolean 값들을 이름있는 속성들로 가지는 객체 같은) Boolean 덩어리를 나타낼 다른 방법이 없다. 비트 마스킹은 또한 코드를 이해하고, 읽고, 유지보수하는데에 있어서 좀 더 어렵게 만드는 경향이 있다. 하지만 이러한 기법은 local storage 의 저장공간이 부족해서 절약하려고 하거나, 네트워크 상에서 각각의 비트를 전송하는 등의 극단적인 상황 같은 굉장히 제한적인 환경에서 필요할 수도 있다. 그래서 비트 마스킹 기법은 크기를 최대한 줄여야하는 상황에서만 사용을 고려해야 한다.</p> + +<h3 id="String_타입">String 타입</h3> + +<p>자바스크립트의 {{jsxref("Global_Objects/String", "String")}} 타입은 텍스트 데이터를 나타내는데 사용한다. 이는 16비트 부호없는 정수 값 요소들의 집합이다. String의 각 요소는 String의 위치를 차지한다. 첫 번째 요소는 0번 인덱스에 있고, 다음 요소는 1번, 그 다음 요소는 2번... 같은 방식이다. String 의 길이는 String이 가지고있는 요소의 갯수이다.</p> + +<p>C 같은 언어와는 다르게, 자바스크립트의 문자열은 변경 불가능 (immutable) 하다. 이것은 한 번 문자열이 생성되면, 그 문자열을 수정할 수 없다는걸 의미한다. 그러나 원래 문자열에서 일부가 수정된 다른 문자열을 만드는건 가능하다. 예를 들자면 이렇다.</p> + +<ul> + <li>원래 문자열에서 각각의 글자를 추출하거나 <code><a href="/en/JavaScript/Reference/Global_Objects/String/substr" title="substr">String.substr()</a></code>을 사용해서 만든 부분 문자열</li> + <li>접합 연산자 (<code>+</code>) 나 <code><a href="/en/JavaScript/Reference/Global_Objects/String/concat" title="concat">String.concat()</a></code> 으로 두 문자열을 합친 문자열</li> +</ul> + +<h4 id="문자열의_자료형화를_조심하라!">"문자열의 자료형화"를 조심하라!</h4> + +<p>문자열을 복잡한 자료형을 표현하는 용도로 쓰는 방법이 꽤나 매력적일 수 있다. 단기적으로 이런 장점들이 있다.</p> + +<ul> + <li>접합 연산자로 손쉽게 복잡한 문자열을 만들 수 있다.</li> + <li>문자열은 디버깅이 쉽다 (화면에 출력한 내용이 문자열 변수에 있는 값과 같다)</li> + <li>문자열은 많은 API 에서 사용하는 공통분모이고 (<a href="/en/DOM/HTMLInputElement" title="HTMLInputElement">입력 필드</a>, <a href="/en/Storage" title="Storage">로컬 스토리지</a> 값, {{ domxref("XMLHttpRequest") }} 요청에서 <code>responseText</code>를 사용할 때 등) 그러다보니 문자열만으로 작업하는게 매혹적일 수 있다.</li> +</ul> + +<p>규칙만 잘 정의해놓는다면, 어떤 자료구조가 되던 문자열로 표시할 수 있다. 그렇다고 해서 이게 좋은 방법이 되는 건 아니다. 예를 들자면, 구분자로 리스트 자료형을 흉내낼 수 있을 것이다 (하지만 자바스크립트의 배열을 사용하는게 더 알맞을 것이다). 불행하게도, 리스트의 요소중에 구분자가 들어있는 요소가 있다면 리스트는 엉망진창이 될 것이다. 물론 탈출 문자 (escape character) 등을 사용하거나 할 수도 있을 것이다. 하지만 이런 것들은 모두 미리 정해놓은 규칙을 필요로 하고, 덕분에 불필요한 관리 부담을 낳는다.</p> + +<p>문자열은 텍스트 데이터에만 사용하자. 복잡한 데이터를 나타낼때는, 문자열을 분석해서 적합한 추상화를 선택해 사용하자.</p> + +<h3 id="Symbol_타입">Symbol 타입</h3> + +<p>Symbol 은 ECMAScript 6 에서 추가되었다. Symbol은 <strong>유일</strong>하고 <strong>변경 불가능한</strong> (immutable) 기본값 (primitive value) 이다. 또한, 객체 속성의 key 값으로도 사용될 수 있다 (아래를 볼 것). 몇몇 프로그래밍 언어에서는 Symbol을 atom 이라고 부른다. 또, C 언어의 이름있는 열거형 (enum) 과도 비슷하다. 좀 더 자세히 알아보려면, 자바스크립트의 {{Glossary("Symbol")}} 와 {{jsxref("Symbol")}} 객체 래퍼 (wrapper) 를 보라.</p> + +<h2 id="객체_Objects">객체 (Objects)</h2> + +<p>컴퓨터 과학에서, 객체는 {{Glossary("Identifier", "식별자 (Identifier)")}} 로 참조할 수 있는, 메모리에 있는 값이다.</p> + +<h3 id="속성_Properties">속성 (Properties)</h3> + +<p>자바스크립트에서, 객체는 속성들을 담고있는 가방 (collection) 으로 볼 수 있다. <a href="/en/JavaScript/Guide/Values,_variables,_and_literals#Object_literals" title="en/JavaScript/Guide/Values,_variables,_and_literals#Object_literals">객체 리터럴 문법 (object literal syntax)</a> 으로 제한적으로 몇 가지 속성을 초기화할 수 있고, 그러고 나서 속성들을 추가하거나 제거할 수도 있다. 속성 값은 객체를 포함해 어떠한 자료형도 될 수 있고, 그 덕분에 복잡한 데이터 구조를 형성하는게 가능해진다. 속성은 키 (key) 값으로 식별된다. 키 값은 String 이거나 Symbol 값이다.</p> + +<p>두 종류의 객체 속성이 있는데, 이들은 종류에 따라 특성값들을 가질 수 있다. 데이터 (data) 속성과 접근자 (accessor) 속성이 그것이다.</p> + +<h4 id="데이터_속성_Data_property">데이터 속성 (Data property)</h4> + +<p>키에 값을 연결하고, 아래와 같은 특성들 (attribute) 이 있다.</p> + +<table class="standard-table"> + <caption>데이터 속성의 특성들</caption> + <tbody> + <tr> + <th>특성 (Attribute)</th> + <th>자료형</th> + <th>설명</th> + <th>기본값</th> + </tr> + <tr> + <td>[[Value]]</td> + <td>JavaScript 타입 모두 가능</td> + <td>이 속성에 대한 get 접근으로 반환되는 값.</td> + <td>undefined</td> + </tr> + <tr> + <td>[[Writable]]</td> + <td>Boolean</td> + <td><code>false</code> 라면, 이 속성의 [[Value]] 을 바꿀 수 없다.</td> + <td>false</td> + </tr> + <tr> + <td>[[Enumerable]]</td> + <td>Boolean</td> + <td><code>true</code> 라면, 이 속성은 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in">for...in</a> 루프에서 열거될 수 있다.</td> + <td>false</td> + </tr> + <tr> + <td>[[Configurable]]</td> + <td>Boolean</td> + <td><code>false</code> 라면, 이 속성은 제거될 수 없고, [[Value]]와 [[Writable]] 외에는 수정될 수 없다.</td> + <td>false</td> + </tr> + </tbody> +</table> + +<h4 id="접근자_속성_Accessor_property">접근자 속성 (Accessor property)</h4> + +<p>값을 가져오거나 값을 저장하기 위해 키에 하나 혹은 두 개의 접근자 함수 (get, set) 연결짓는다. 아래와 같은 특성이 있다.</p> + +<table class="standard-table"> + <caption>접근자 속성</caption> + <tbody> + <tr> + <th>특성 (Attribute)</th> + <th>자료형</th> + <th>설명</th> + <th>기본값</th> + </tr> + <tr> + <td>[[Get]]</td> + <td>Function 객체 혹은 undefined</td> + <td>이 속성의 값에 접근할 때마다, 인자 목록 없이 함수가 호출되고, 함수의 반환된 값으로 속성값을 가져온다. <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/get"><code>get</code></a> 을 볼 것</td> + <td>undefined</td> + </tr> + <tr> + <td>[[Set]]</td> + <td>Function 객체 혹은 undefined</td> + <td> + <p>이 속성의 값이 바뀌려고 할 때마다, 할당된 값을 인자로 함수가 호출된다. <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/set"><code>set</code></a> 을 볼 것</p> + </td> + <td>undefined</td> + </tr> + <tr> + <td>[[Enumerable]]</td> + <td>Boolean</td> + <td><code>true</code> 라면, 이 속성은 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in">for...in</a> 루프에서 열거될 수 있다.</td> + <td>false</td> + </tr> + <tr> + <td>[[Configurable]]</td> + <td>Boolean</td> + <td><code>false</code> 라면, 이 속성은 제거될 수 없고, 데이터 속성을 수정할 수 없다.</td> + <td>false</td> + </tr> + </tbody> +</table> + +<h3 id="Normal_objects_and_functions">"Normal" objects, and functions</h3> + +<p>자바스크립트 오브젝트는 키와 값의 매핑이다. 키는 문자열이고 값은 다른 어떤 값도 될 수 있다. 오브젝트는 <a class="external" href="http://en.wikipedia.org/wiki/Hash_table">hashmaps</a>을 표현하는데 적합하다. 표준이 아닌 <a href="/en/JavaScript/Reference/Global_Objects/Object/proto" title="__proto__">__proto__</a> 슈도 프로퍼티를 사용할 때는 주의하자. 이것을 지원하는 환경에서는 <code>'__proto__'는 오브젝트의 프로토타입을 의미하므로 이 이름을 키로 사용할 수 없다. 속성을 사용할 수 없다. 문자열의 출처가 분명하지 않을 때(입력 필드의 입력값 등)</code>주의가 필요하다. <a class="external" href="http://productforums.google.com/forum/#!category-topic/docs/documents/0hQWeOvCcHU">이런 일이 생길 수도 있다</a>. 이 때는 <a class="external" href="http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/StringMap.js?r=4779">StringMap abstraction</a> 같은 대안을 사용해보자.함수는 일반 오브젝트에서 호출 가능한 특성을 추가한 오브젝트이다.</p> + +<h3 id="Dates">Dates</h3> + +<p>시간을 나타내려면 <a href="/en/JavaScript/Reference/Global_Objects/Date" title="en/JavaScript/Reference/Global_Objects/Date">Date utility</a>를 사용하자. 최고의 선택이다.</p> + +<h3 id="Arrays">Arrays</h3> + +<p><a href="/en/JavaScript/Reference/Global_Objects/Array" title="Array">배열(Arrays</a>) 는 정수키를 가지는 일련의 값들을 표현하기 위한 오브젝트이다. 배열 오브젝트에는 길이를 나타내는 'length'란 속성도 있다. 배열은 Array.prototype을 상속받으므로 배열을 다룰 때 편한 <a href="/en/JavaScript/Reference/Global_Objects/Array/indexOf" title="en/JavaScript/Reference/Global_Objects/Array/indexOf">indexOf</a> (배열에서 값 검색)와 <a href="/en/JavaScript/Reference/Global_Objects/Array/push" title="en/JavaScript/Reference/Global_Objects/Array/push">push</a> (새로운 값 추가) 같은 함수를 사용할 수 있다. 배열은 리스트나 집합을 표현하는데 적합하다.</p> + +<h3 id="WeakMaps_Maps_Sets">WeakMaps, Maps, Sets</h3> + +<p>표준이 아니지만 ECMAScript 6에서 표준이 될 것 같다.</p> + +<p>이 자료형들에서는 키가 문자열 뿐만 아니라 오브젝트도 될 수 있다. Set은 오브젝트의 집합을 나타내는 반면에 WeakMaps와 Maps는 오브젝트에 값을 연관시킬 수 있다. Map과 WeakMap의 차이는 전자는 오브젝트 키를 열거할 수 있다는 것이다. 이것은 가비지 콜렉션에서 이점을 준다.</p> + +<p>ECMAScript 5를 이용해서 Map과 Set을 구현할 수 있을 것이다. 그러나 오브젝트는 크기 비교가 안된다는 점 때문에(예를들어 어떤 오브젝트는 다른 오브젝트보다 '작다'라고 할 수 없다) look-up에 소요되는 시간이 선형 시간이지 않을 것이다. 네이티브 구현은(WeakMaps를 포함해서) look-up 시간이 거의 로그 시간에서 상수 시간이다.</p> + +<p>DOM 노드에 데이터를 지정하기 위해서 직접 속성을 지정할 수도 있지만 data-* 속성을 사용할 수도 있다. 여기에는 다른 스크립트도 모두 그 속성에 접근할 수 있다는 나쁜 점이 있다. Map과 WeakMap은 오브젝트만 사용할 수 있는 개인 데이터를 쉽게 만들 수 있게 해준다.</p> + +<h3 id="TypedArrays">TypedArrays</h3> + +<p>표준이 아니지만 ECMAScript 6에서 표준이 될 것 같다.</p> + +<h2 id="더_보기">더 보기</h2> + +<ul> + <li><a class="link-https" href="https://github.com/nzakas/computer-science-in-javascript/">Nicholas Zakas collection of common data structure and common algorithms in JavaScript.</a></li> +</ul> |