2012-09-02 2 views
2

일부 언어는 문자열이 아닌 키를 키로 사용할 수있는 해시 테이블을 구현합니다. JavaScript에서는 문자열과 숫자로 제한됩니다. 이런 종류의 구현에 대한 조회가 여전히 O (1)입니까? JavaScript로 구현 되었습니까?JavaScript에서 해시 테이블을 구현하는 방법

+0

당신은 "해시 개체"무슨 뜻인지 명확히 할 수 있습니다 : 예를 들어,

function ComplexKey(a,b) { this.a = a; this.b = b; } ComplexKey.prototype.toString = function() { return this.a + ':' + this.b; } var o = {}; o[new ComplexKey(1,2)] = 'x'; o[new ComplexKey(3,4)] = 'y'; 

결과? 클라이언트 측'new Object(); 또는 var foo = {};'객체 유형 또는 "시스템"(예 : C++)에서 사용하는 기본 데이터 구조? – scunliffe

답변

9

분명히이 주제에 대해 많은 오해가 있습니다. JavaScript에서 객체의 키는 실제로 문자열 인 (§8.10 참조) 만 있습니다. 무엇이든 (숫자 포함)을 객체 키로 사용하여 문자열로 변환합니다. 따라서 obj[1]obj["1"]입니다.

내부적으로 많은 JS 구현은 개체 속성을 빠르게 검색 할 수 있도록 일종의 해시 테이블을 사용합니다. V8 실제로 generates hidden C++ classes 단일 CPU 명령에서 조회를 실행할 수 있습니다. 어느 쪽이든, 객체 속성 액세스가 빠르며 O (1) 근처에 있다고 가정하는 것이 안전합니다.

모든 개체 속성 키가 문자열로 변환 되었기 때문에 문자열로 변환하는 항목 만 키로 사용할 수 있습니다. 숫자가 자연스럽게 문자열로 변환되기 때문에 잘 작동합니다. 불리언들도 마찬가지입니다. Date 인스턴스가 고유 문자열로 변환되기 때문에 날짜도 작동합니다 (알고 있어야하는 가장자리 사례가 있음에도 불구하고).

그러나 개체는 의미있는 문자열로 변환되지 않습니다.예를 들면 다음과 같습니다 때문에 string conversion rules

o = { '[object Object]': 'some value' } 

:

var o = {}; 
o[{a:1}]='some value'; 

사실을 초래한다. 모든 개체가 으로 변환되므로 많은 개체를 다른 개체의 키로 추가하면 하나의 속성 만있는 개체가됩니다.

물론 개체를 키로 사용할 수 있습니다. 사실상 toString —의 기본 구현을 재정의해야만 자신의 해싱 알고리즘을 만들 수 있습니다.

o = { 
    '1:2': 'x', 
    '3:4': 'y' 
} 
+0

이론적으로 해시 [JSON.toString (obj)]로 저장 한 객체를 사용할 수 있습니까? – MaiaVictor

+1

개체에 순환 참조가 없으면 '예'입니다. ('JSON.stringify'와 함께) – josh3736

+0

고맙습니다. 매우 유익한 대답. 그래서 아무런 문제없이 JSON.toString에 의해 생성 된 수천 개의 키가있는 해시에 지속적으로 조회 할 수 있습니까? – MaiaVictor

4

JavaScript에는 "해시 테이블"이 없습니다.

키가 고유해야한다는 제한과 함께 키/값 쌍의 모음 인 Dictionaries이 있습니다. 차이점은 사전 구현이 해시를 의미하지는 않지만 성능상의 이유로 구현시 내부적으로 Hash table이 사용된다는 것입니다.

모두 JavaScript의 개체는 사전 (예 : stringnumber과 같은 제외 된 기본 유형)에서 작동합니다.

var o = {}; 
o[propExpression] = valueExpression; 

그러나 여기에서 중요한 것은 : 일반적으로 빈 객체는 일반적인 "해시 테이블"에 사용되는 모든 재산/키 값이 먼저를 문자열로 변환됩니다.

따라서 다음과 동일하다

을 : ECMA 스크립트는 다소 혼란을

o[true] = 1 
o["true"] = 1 
따르는하지만 속성 이름 Property Descriptors 검색된 모든 문자열 "알지"의 핵심

속성 식별자 유형은 속성 이름을 속성 설명자와 연결하는 데 사용됩니다. 속성 식별자 유형의 값은 형식 (이름, 설명자), 쌍이며 name은 문자열이고 설명자는 속성 설명자 값입니다.

+0

"해시 테이블"과 사전이 키가 구성된 양식 간의 기능상의 차이점은 무엇입니까? 기능상의 차이점은 무엇입니까? –

+0

구현이 가능하지 않습니까? – MaiaVictor

+1

@JaredFarrish 사전은 해싱 기능없이 구현 될 수 있습니다. 키 - 값 쌍의 순서. Hashtable은 해시 함수를 의미합니다. 내부적으로는 Hashtable을 사용하여 속성을 복원 할 수 있습니다 (어쩌면 한도로 제어 할 수도 있음). 그러나 ECMAScript 사양에서 해시 함수를 지정하는 객체에 대한 "해시 코드"또는 능력에 대한 규정은 없습니다. 구현체는 Hashtable을 사용하도록 선택한 경우 내부적으로 해시 함수 (문자열 속성 이름)를 사용합니다. –

관련 문제