JavaScript 哈希映射是如何实现的?
Posted
技术标签:
【中文标题】JavaScript 哈希映射是如何实现的?【英文标题】:How is a JavaScript hash map implemented? 【发布时间】:2012-02-11 06:08:24 【问题描述】:我目前使用 OpenLayers,并且有大量数据要绘制到矢量图层(超过 100000 个矢量)。
我现在正尝试将所有这些向量放入 javascript 哈希映射中以分析性能。我想知道JavaScript中的hash map是如何实现的,是真正的hash函数还是只是一个使用简单数据结构和搜索算法的包装函数?
【问题讨论】:
JS实现不止一种,所以没办法回答。 ECMAScript 没有指定对象使用什么数据结构,也没有指定访问时间的限制。散列是典型的,但可以使用平衡树。 ES6 有纯 Maps。该链接描述了普通对象和 Map 之间的区别、关键细节等:MDN JavaScript Map 【参考方案1】:每个 javascript object 都是一个简单的 hashmap,它接受字符串或 Symbol 作为其键,因此您可以将代码编写为:
var map = ;
// add a item
map[key1] = value1;
// or remove it
delete map[key1];
// or determine whether a key exists
key1 in map;
javascript对象在其实现上是一个真正的hashmap,所以搜索的复杂度是O(1),但是对于javascript字符串没有专门的hashcode()
函数,它是由javascript引擎内部实现的(V8,SpiderMonkey,JScript .dll等...)
2020 年更新:
现在的javascript 也支持其他数据类型:Map
和WeakMap
。与传统对象相比,它们的行为更接近于哈希映射。
【讨论】:
完美。我之前使用过 $('div#someDiv').data(key, value) ,这个更简单,并且可能对旧浏览器也有更好的支持。谢谢 有没有办法找到地图的长度? @Sridhar 使用 Object.keys(map).length 请注意,您可以使用数字作为键map[2] = 'foo'
,但它会在内部转换为字符串 > map = '2': 'foo'
@otakustay 这是我今天才知道的超酷功能 :) 真的我需要密切学习 Javascript。【参考方案2】:
这是一种使用类似于 Java map 的简单方便的方法:
var map=
'map_name_1': map_value_1,
'map_name_2': map_value_2,
'map_name_3': map_value_3,
'map_name_4': map_value_4
并获得价值:
alert( map['map_name_1'] ); // fives the value of map_value_1
...... etc .....
【讨论】:
【参考方案3】:JavaScript 对象不能纯粹在哈希映射之上实现。
在您的浏览器控制台中试试这个:
var foo =
a: true,
b: true,
z: true,
c: true
for (var i in foo)
console.log(i);
...您会按照插入顺序收到它们,即de facto standard 行为。
哈希映射本质上不维护顺序,因此 JavaScript 实现可能以某种方式使用哈希映射,但如果这样做,它至少需要一个单独的索引和一些额外的插入簿记。
这是Lars Bak explaining why v8 doesn't use hash maps to implement objects的视频。
【讨论】:
"otakustay 在技术上是错误的,是最糟糕的错误。"这有点苛刻。它可能不是 1:1,但出于使用像字典这样的哈希的意图和目的,它以相同的方式工作。 只是想澄清一下,这对于 JavaScript 的某些实现(例如大多数浏览器)可能是正确的,但不一定总是正确的。键的迭代顺序不是由 ECMAScript 标准定义的,可以是任何顺序,但仍然是有效的 JS 实现。 与某些实现是否使用散列的问题不同,它们是否还保留插入顺序的键列表以方便用户使用与原始问题无关。【参考方案4】:<html>
<head>
<script type="text/javascript">
function test()
var map= 'm1': 12,'m2': 13,'m3': 14,'m4': 15
alert(map['m3']);
</script>
</head>
<body>
<input type="button" value="click" onclick="test()"/>
</body>
</html>
【讨论】:
【参考方案5】:虽然普通的旧 JavaScript 对象可以用作映射,但它们通常以保留插入顺序的方式实现以与大多数浏览器兼容(请参阅 Craig Barnes 的回答),因此不是简单的哈希映射。
ES6 引入了正确的 Maps(参见 MDN JavaScript Map),其中 standard says:
Map 对象必须使用哈希表或其他机制来实现,平均而言,这些机制提供的访问时间与集合中的元素数量呈次线性关系。
【讨论】:
【参考方案6】:你要不要试试这门课Map
:
var myMap = new Map();
// setting the values
myMap.set("1", 'value1');
myMap.set("2", 'value2');
myMap.set("3", 'value3');
console.log(`Map size: $myMap.size`); // 3
// getting the values
console.log(`Key: "1", Value: $myMap.get("1")`); // "value associated with "value1"
console.log(`Key: "2", Value: $myMap.get("2")`); // "value associated with "value2"
console.log(`Key: "3", Value: $myMap.get("3")`); // "value associated with "value3"
注意:key
和 value
可以是任何类型。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
【讨论】:
【参考方案7】:我遇到了带有一些通用键的 json 的问题。我想将所有具有相同键的值分组。经过一番冲浪,我找到了hashmap package。这真的很有帮助。
为了对具有相同键的元素进行分组,我使用了multi(key:*, value:*, key2:*, value2:*, ...)
。
这个包有点类似于 Java Hashmap 集合,但没有 Java Hashmap 强大。
【讨论】:
以上是关于JavaScript 哈希映射是如何实现的?的主要内容,如果未能解决你的问题,请参考以下文章