微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JavaScript是否将哈希表用于Map和Set?

如何解决JavaScript是否将哈希表用于Map和Set?

我是Python开发人员,是我使用JavaScript的第一步。

我开始使用MapSet。它们似乎与Python中的dictset具有相同的API,因此我认为它们是一个哈希表,我可以依靠O(1)查找时间。

但是,出于好奇,我试图查看如果在Chrome的控制台中执行此操作会发生什么情况:

new Set([new Set([1,2,3])])

这是怎么回事:

Set(1) {Set(3)}

JavaScript可以愉快地创建集合。怎么会这样?在Python中,由于无法将可变项放入集合或字典中,因此会出现错误。 JavaScript为什么允许它?

解决方法

考虑以下JS代码:

> m1 = new Map([['a',1]])
Map { 'a' => 1 }
> m2 = new Map()
Map {}
> m2.set(m1,3)
Map { Map { 'a' => 1 } => 3 }
> m2.get(m1)
3

但是请注意,它是基于身份的哈希,即===,所以...

> m2.get(new Map([['a',1]]))
undefined

那么,这张地图真的有用吗?

注意,这与Python的默认行为没什么不同。用户定义类型的默认状态为可散列:

>>> class Foo: pass
...
>>> f0 = Foo()
>>> s = {f0}
>>> Foo() in s
False
>>> f0 in s
True

在Python中,默认情况下,object.__eq__将基于身份进行比较,因此上面的方法很好。但是,如果您覆盖__eq__,默认情况下,__hash__设置为None,尝试使用基于哈希的容器将失败:

>>> class Bar:
...    def __init__(self,value):
...       self.value = value
...    def __eq__(self,other):
...       return self.value == other.value
...
>>> b0 = Bar(0)
>>> b1 = Bar(2)
>>> {b0,b1}
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
TypeError: unhashable type: 'Bar'

在这一点上,您必须实现__hash____eq__保持一致,但是请注意,用户定义的对象永远不会真正非常“不变”

,

这些数据结构的内部表示形式取决于运行代码的引擎(例如V8或Chakra)。但是,该规范要求引擎在以下位置实现这些结构

提供访问时间的机制在集合中的元素数量上是次线性的。

来自ECMAScript® 2021 Language Specification - 23.1 Map Objects

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。