对象和哈希之间的区别是什么?

67

在JavaScript中,对象和哈希之间有什么区别?如何创建它们,为什么要关心它们?下面的代码示例有区别吗?

var kid = {
 name: "juni",
 age: 1
}

并且:

var kid = new Object();
kid.name = "juni";
kid.age = 1;

并且:

var kid = new Object();
kid["name"] = "juni";
kid["age"] = 1;

你能想到其他需要说明的代码示例吗?

这里的核心问题对象和哈希之间的区别是什么?


2
我认为你的陈述“对象和哈希之间的区别”是指“对象和(哈希)映射之间的区别”。 - Peter
8
在 JavaScript 中,没有所谓的哈希类型。{} 只是 Object 类型的一种简写初始化方式。而 [] 则是 Array 类型的一种简写初始化方式。 - Blixt
1
也许是原型哈希类让我感到困惑:http://www.prototypejs.org/api/hash - Landon Kuhn
1
如果您只想存储键/值对,那么在Prototype中绝对不需要使用“Hash”类型。 - SolutionYogi
@landon9720 - 关于 其他代码示例 的问题 - 三个原始示例都是 匿名对象。您也可以声明一个类 Kid,它看起来很像您的第二个示例。但是,根据您如何检查 var kid 是否为 Object,您可能会得到不同的答案。请参见:https://dev59.com/S2oy5IYBdhLWcg3wfeMR - Jesse Chisholm
显示剩余3条评论
11个回答

64

没有任何差别。这三个字面上是相等的。


4
然而,在这里https://dev59.com/S2oy5IYBdhLWcg3wfeMR,他们展示了不同的`isObject`实现可能会给出不同的答案。 - Jesse Chisholm

19

这两种符号表示法可以互换使用。在许多情况下,使用方括号语法[ ]更具吸引力,例如当使用变量引用对象时。

var temp  = "kid";
var obj = new Object();
obj[temp] = 5; // this is legal, and is equivalent to object.kid
obj.temp = 5; // this references literally, object.temp

6

在其他编程语言比如Java和C#中,可以使用任何对象(不仅仅是字符串或数字)作为哈希表/哈希映射的键,但在JavaScript中并非如此:键只是被转换成字符串。

var h = {}, k = {};
h[k] = "One";
alert( h[ "[object Object]" ] ); // Alerts "One"

使用任意对象作为键可能是有用的,这种情况下可以使用类似jshashtable的东西。

免责声明:我写了jshashtable。


5

实际上,JavaScript 中的每个对象都是一个哈希表。这是对象属性和方法的哈希表。事实上,JavaScript 中的所有东西都是哈希表(即名称/值对列表)。

每次调用对象的方法、属性或仅仅是引用任何变量时,都会执行内部哈希查找。


简单来说,每个 JavaScript 对象都是一个通用的映射而不是哈希表。在像 Java、C# 等语言中,映射通常用于同类数据,而在 JavaScript 中,map 的数据可以是不同类型的。 - lcn

4

您的所有示例中并没有任何区别。它们都是具有命名属性的对象。您只是展示了创建/引用这些属性的不同方式。


3

它们是相同的。

你可以互换使用它们。


3

我认为这些是相同的。第三个版本可以用于动态属性名称。第一个版本写起来最短。


2

它们是相同的。就像[]new Array()是相同的。

如果您想了解更多关于JavaScript核心类型的信息,请查看MDC Core JavaScript 1.5参考文档

如果您需要证明{}new Object()相同:

Object.prototype.helloWorld = function () { alert('Foo!'); };
var a = new Object();
var b = {};
a.helloWorld();
b.helloWorld();

!!! 警告 ACHTUNG AVERTISSEMENT !!! 在生产代码中绝不要将prototype属性分配给Object类型。否则会污染整个全局命名空间。


1

从技术角度来看,它们是相同的。当您编写代码时,您可以轻松地执行myobject['someproprty' + 'somethingElseConcatenated],但使用“点表示法”时则不行-您只能执行myobject.someproperty

Douglas Crockford是ECMAscript的作者之一,他建议不要使用var a = new Object()语法,原因我没有完全了解。无论如何,如果您对此感兴趣,观看他的演示会很值得参考(它由几个部分组成,第一个部分在这里http://video.yahoo.com/watch/111593/1710507)。


1
每个引擎(浏览器)的实现方式都不同,但让我们专注于Chrome的V8(根据我一年前在大多数现代浏览器上进行的性能测试,如果您遵循v8指南,它们都会提供类似的性能提升)。
基本上发生的事情是:
1. 实现动态对象,可以在其中添加和删除属性-散列表是最简单的解决方案,但从速度上来看,它不如Java中的常规对象高效(随机访问...)。 2. V8尝试根据几种策略猜测您的对象是常规对象(具有特定顺序的最终属性集等)还是散列表。首先,它假设这是一个简单的对象,并且每个新属性都会导致创建一个新的对象结构并将旧对象复制到其中,以及新属性。如果将对象归类为“困难”-则将其移动到散列表中。 3. 如果V8注意到太多的“错误”-它将所有内容移动到散列表中-因此,您将获得较差的性能(这就是为什么要使用初始化所有成员或在json中初始化的结构的构造函数的原因...)
请参见以下链接: https://developers.google.com/v8/design#prop_access

www.quora.com/Are-JavaScript-Objects-implemented-as-HashTables-Is-key-value-access-O-1

jayconrod.com/posts/52/a-tour-of-v8-object-representation

这是一场非常好的演讲: https://www.youtube.com/watch?v=UJPdhx5zTaw

希望对您有所帮助...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接