关联数组的执行方式类似于哈希表吗?

时间:2013-05-29 23:24:10

标签: javascript hashtable associative-array

因此,假设您在JavaScript中有一个关联数组:

var hashTable = {};

hashTable["red"] = "ff0000";
hashTable["green"] = "00ff00";
hashTable["blue"] = "0000ff";

检索如下值时会发生什么:

var blue = hashTable["blue"];

性能是否与其他语言的哈希表类似?我的意思是,是否存在用于确定属性位置的实际哈希函数,或者是否存在循环搜索,例如:

for (var color in hashTable) {
    if (hashTable.hasOwnProperty(color)) {
        //look for matching key
    }
}

实施方式因浏览器而异吗?我找不到任何与此特定主题相关的内容。感谢。

3 个答案:

答案 0 :(得分:4)

它在不同的javascript引擎中的实现方式不同,而现在看来,对象并没有“类字典”数据结构的支持。

来自https://developers.google.com/v8/design

  

JavaScript是一种动态编程语言:可以动态地向对象添加和删除属性。这意味着对象的属性可能会发生变化。大多数JavaScript引擎使用类似字典的数据结构作为对象属性的存储 - 每个属性访问都需要动态查找来解析属性在内存中的位置。这种方法使得访问JavaScript的属性通常比访问Java和Smalltalk等编程语言中的实例变量要慢得多。在这些语言中,由于对象类定义的固定对象布局,实例变量位于由编译器确定的固定偏移处。访问只是内存加载或存储的问题,通常只需要一条指令。

     

为减少访问JavaScript属性所需的时间,V8不使用动态查找来访问属性。相反,V8在幕后动态创建隐藏类。这个基本思想并不新鲜 - 基于原型的编程语言Self使用map来做类似的事情。在V8中,当添加新属性时,对象会更改其隐藏类。

Firefox的IonMonkey做了类似的事情。通过与Mozilla(http://www.infoq.com/news/2011/05/ionmonkey)的开发人员的访谈:

  

动态语言可能没有任何固有的优化优势,但它们确实具有静态语言所没有的有趣优化。例如,当您编写JavaScript时,对象在用户看来是哈希表,将属性名称映射到值。如果它们实际上是这样实现的,它们会很慢并且会占用大量内存。

     

一个好的引擎能够在内部对看起来相同的对象进行分组,从中提取类似内部Java的类。然后,JIT可以将对象视为具有实际类型,生成超快速代码,避免昂贵的属性查找。

答案 1 :(得分:3)

Javascript实际上没有“关联数组”。 {}会返回一个JavaScript 对象,它可以包含命名属性以及原型,它允许对象继承其他对象的属性。

因此,性能不会像Hash表那样,因为属性可以从其原型对象继承,并且按名称搜索给定属性可能需要在找到原型树之前遍历它。

此博客文章也可能提供一些见解:

  

http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/

答案 2 :(得分:0)

术语associative array描述了它的用法:它是一个用于将一个事物与另一个事物相关联的键值容器。但是术语hash table描述了它的实现:它使用哈希函数来定位底层数组中的元素。在某些实现中可能有associative array使用红黑树或其他数据结构但不使用哈希表。