jshashtable 指出:
JavaScript 的内置对象确实使用方括号表示法提供了哈希表功能,前提是您的键是字符串或数字:
据我所知,键只是字符串,(因为无论如何数字都被强制转换为字符串)。我只是想检查并确保上面所说的是错误的(因为键不能是数字)。
ECMA 标准是否对此有任何说明..
还是特定于浏览器的实现?
jshashtable 指出:
JavaScript 的内置对象确实使用方括号表示法提供了哈希表功能,前提是您的键是字符串或数字:
据我所知,键只是字符串,(因为无论如何数字都被强制转换为字符串)。我只是想检查并确保上面所说的是错误的(因为键不能是数字)。
ECMA 标准是否对此有任何说明..
还是特定于浏览器的实现?
JavaScript 的内置对象确实使用方括号表示法提供了哈希表功能,前提是您的键是字符串或数字
这似乎是不正确的 -对象键 总是字符串,可能是字符串或(自 ECMAScript 2015 起,又名 ECMA-262 ed 6)符号。但这与方括号属性访问是不同的主题。
请参阅 ECMA-262 ed 3 § 11.2.1(另请参阅ECMAScript 2017(草案)。):
属性通过名称访问,使用点符号:
成员表达式。标识符名称
调用表达式。标识符名称
或括号符号:
成员表达式 [ 表达式 ]
CallExpression [ 表达式 ]
点符号由以下语法转换解释:
成员表达式。标识符名称
其行为与
MemberExpression [ <identifier-name-string> ]
同样
调用表达式。标识符名称
其行为与
CallExpression [ <identifier-name-string> ]
其中<identifier-name-string>是一个字符串文字,在处理 Unicode 转义序列后包含与 IdentifierName 相同的字符序列。
因此,在使用点表示法时,点后的位必须符合 IdentifierName 的标准。但是当使用方括号时,会提供一个表达式,该表达式被计算并解析为一个字符串。
简而言之,提供方括号表示法,以便可以使用表达式访问属性,例如
var y = {};
var x = 'foo';
y[x] = 'foo value';
在上面,x
在方括号中提供,因此它被评估,返回字符串'foo'。由于此属性尚不存在y
,因此已添加。然后将的foo
属性y
赋值为“foo value”。
一般而言,计算方括号中的表达式并toString()
调用其方法。正是该值用作属性名称。
在点属性访问方法中,不评估标识符,因此:
y.bar = 'bar value';
创建bar
一个值为的属性bar value
。
如果要创建数字属性,则:
y[5] = 5;
将评估5
,看到它不是一个字符串,调用(或多或少)Number(5).toString()
返回字符串5
,用于属性名称。然后为它分配值5
,这是一个数字。
这个答案是在 ECMAScript ed3 最新时写的,但是事情已经发生了变化。请参阅后面的参考资料和MDN。
你是对的键只能是字符串,而数组中使用的数字键被强制并存储为字符串。
var arr = [true];
arr[0] === true;
arr['0'] = false;
arr[0] === false;
ECMAScript 规范,第 42 页:ECMA-262 脚本第 3 版。
生产PropertyName : NumericLiteral
评估如下:
好吧,这是我的答案——主要是因为我对其他(正确)答案中的引用不满意—— [] 中属性名称的表达式总是被强制转换为字符串,并且这种行为在规范中得到了很好的定义。因此,根据对相关引用的解释,它可能会被视为误导和/或不正确。
但是,引用并不假定x[42]
和x["42"]
不同;它指出-与其他原语和信息的误导排除-只有字符串和数字可作为正常属性解析“散列键”(真正的属性名称),在这个意义上,报价可以说是正确的。
这些规则来自标准 ECMA-262 ECMAScript 语言规范第 5 版(2009 年 12 月)
来自“11.2.1 属性访问器”部分(省略产生式规则):
产生式 MemberExpression : MemberExpression [ Expression ] 的计算方式如下:
- 让 baseReference 成为评估 MemberExpression 的结果。
- 令 baseValue 为 GetValue(baseReference)。
- 让 propertyNameReference 成为计算 Expression 的结果。
- 让 propertyNameValue 为 GetValue(propertyNameReference)。
- 调用 CheckObjectCoercible(baseValue)。
- 令 propertyNameString 为 ToString(propertyNameValue)。
- 如果正在评估的语法产生式包含在严格模式代码中,则让 strict 为真,否则让 strict 为假。
- 返回一个 Reference 类型的值,其基值为 baseValue,引用名称为 propertyNameString,且其严格模式标志为严格。
快乐编码。
键总是字符串。这意味着您不能使用对象实例的身份作为键。
在 Flash 的 ActionScript 3(与 AS2 不同,使用强运行时类型)中有一个 Dictionary 对象,它对键使用严格的相等比较,因此您可以将对象实例本身用作键(以及数字、字符串等)。
如果您想在 JavaScript 中做同样的事情,那会很困难,因为您必须生成自己唯一的对象 ID 并将它们附加到您想要跟踪的每个对象。有些人建议向 Object 类添加原型函数,但这会不必要地增加每个对象的开销。在任何情况下,您都希望通过函数调用为对象提供可跟踪 ID,该函数调用将递增的静态编号分配给诸如“ __objectid__
”之类的唯一属性。
然后可以想象使用 Add(key,value) 等方法创建一个类似字典的类,但它必须将字符串、数字和对象存储在三个单独的内部散列中,以确保“3”不会与数字 3 或 id 为 3 的对象。 add 方法必须自动将 分配__objectid__
给任何尚未分配 id 的对象类型的键。即便如此,您也无法使用方括号访问字典,除非在 JavaScript 中存在一些我不知道的属性分配挂钩。
这是一个functor Array
. 它在使用函数式编程范式时很有用。
javascript:
alert(["Using ",window.navigator.userAgent] );
FunctorRA=[]; f=function(){return f}; g=function(x){return x};
FunctorRA[f]=43;
FunctorRA[g(function(){})]="generic";
FunctorRA[g(g)]="idempotent";
alert(FunctorRA);
for (i in FunctorRA)
alert([ "Functor[ ", i,
"]'s\n\n value is \n\n", FunctorRA[i]].join(""));
显示:
Using ,Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423
Ubuntu/10.04 (lucid) Firefox/3.6.3
一个空alert
然后:
Functor[ function () {
return f;
}]'s
value is
43
等等。
注意本:
alert( FunctorRA )
显示.toString()
不枚举非数字索引FunctorRA
是数组“服装”中的通用对象.
语法等价物(即使使用字符串eval
强制)在 javascript 中:
将冒号嵌入到函数名称中的详细信息,即使它通常是在语法上描述初始值设定项属性、标签、?:
(条件表达式)等的分隔符。.
要求转义所有语法上重要的 JavaScript 字符存在类似的问题代码如(){}\n .,
.... []
作为一个整体,该构造有效地为括号内包含的表达式执行此操作,大概是通过将字符串的评估推迟为 String 类型的对象。这与事实相似43.x=2
是禁止的但如果43被表示为通过Number类型的对象(43).x=2
或43["x"]=2
。(证明:javascript:alert( [ (43).x=2, 43["x"]=2 ] )
显示2,2
但javascript:alert(43.x=2)
产生错误)。