jshashtable状态:
JavaScript的内置对象使用方括号表示属性提供哈希表功能,前提是您的键是字符串或数字:
据我所知,键只是字符串,(因为数字被强制转换成字符串).我只想检查并确保上面所述的内容是错误的(因为密钥不能是数字).
ECMA标准是否说明了这一点......
或者是特定于浏览器的实现?
Rob*_*obG 32
JavaScript的内置对象使用方括号表示属性提供哈希表功能,前提是键是字符串或数字
这似乎是不正确的 - 对象键 总是字符串可能是字符串或(因为ECMAScript 2015,又名ECMA-262 ed 6)符号.但这是方括号属性访问的另一个主题.
参见ECMA-262 ed3§11.2.1(另请参见ECMAScript 2017(草案).):
使用点表示法按名称访问属性:
MemberExpression.IdentifierName
CallExpression.IdentifierName
或括号表示法:
MemberExpression [Expression]
CallExpression [Expression]
点符号由以下语法转换解释:
MemberExpression.IdentifierName
它的行为是完全相同的
MemberExpression [<identifier-name-string>]
和类似的
CallExpression.IdentifierName
它的行为是完全相同的
CallExpression [<identifier-name-string>]
其中<identifier-name-string>是在将Unicode转义序列作为IdentifierName处理后包含相同字符序列的字符串文字.
因此,当使用点表示法时,点后面的位必须符合IdentifierName的条件.但是当使用方括号时,会提供一个表达式,该表达式将被计算并解析为字符串.
简言之,提供方括号表示法,以便可以使用表达式访问属性,例如
var y = {};
var x = 'foo';
y[x] = 'foo value';
Run Code Online (Sandbox Code Playgroud)
在上面,x
在方括号中提供,因此它被评估,返回字符串'foo'.由于此属性尚未存在y
,因此会添加该属性.然后为foo
属性y
赋值为'foo value'.
一般而言,评估方括号中的表达式并toString()
调用其方法.它是用作属性名称的值.
在dot属性访问方法中,不评估标识符,因此:
y.bar = 'bar value';
Run Code Online (Sandbox Code Playgroud)
创建bar
具有值的属性bar value
.
如果要创建数字属性,则:
y[5] = 5;
Run Code Online (Sandbox Code Playgroud)
将评估5
,看到它不是一个字符串,调用(或多或少)Number(5).toString()
返回字符串5
,用于属性名称.然后5
为其分配值,即数字.
这个答案是在ECMAScript ed3是最新的时候编写的,但事情已经发生了变化.请参阅后面的参考资料和MDN.
你是正确的键只能是字符串,并且数字键(例如在数组中使用的数字键)被强制并存储为字符串.
var arr = [true];
arr[0] === true;
arr['0'] = false;
arr[0] === false;
Run Code Online (Sandbox Code Playgroud)
ECMAScript规范,第42页:ECMA-262脚本第3版.
生产PropertyName : NumericLiteral
评估如下:
小智 5
好吧,这是我的答案 \xe2\x80\x94 主要是因为我对其他(正确)答案中的引用不满意\xe2\x80\x94 [ ] 中属性名称的表达式总是被强制转换为字符串,这种行为很好规范中定义。因此,取决于解释相关引文的解释,它可能被视为误导和/或不正确。
\n然而,引用并不假定 和x[42]
是x["42"]
不同的;它指出\xe2\x80\x94,误导性地排除了其他原语和细节\xe2\x80\x94,在正常属性解析下,只有字符串和数字可用作“散列键”(真正的属性名称),从这个意义上说,引用可以说是正确的。
这些规则来自标准 ECMA-262 ECMAScript 语言规范第 5 版(2009 年 12 月)。
\n来自“11.2.1 属性访问器”部分(省略生产规则):
\n\n\n产生式 MemberExpression : MemberExpression [ Expression ] 的计算如下:
\n\n
\n- 令 baseReference 为对 MemberExpression 求值的结果。
\n- 令 baseValue 为 GetValue(baseReference)。
\n- 令 propertyNameReference 为计算 Expression 的结果。
\n- 令 propertyNameValue 为 GetValue(propertyNameReference)。
\n- 调用 CheckObjectCoercible(baseValue)。
\n- 令 propertyNameString 为 ToString(propertyNameValue)。
\n- 如果正在评估的语法产生式包含在严格模式代码中,则令 strict 为 true,否则令\nstrict 为 false。
\n- 返回引用类型的值,其基值为 baseValue,其引用名称为\npropertyNameString,其严格模式标志为 strict。
\n
键总是字符串。这意味着您不能使用对象实例的身份作为键。
在 Flash 的 ActionScript 3(与 AS2 不同,使用强运行时类型)中有一个 Dictionary 对象,它对键使用严格的相等比较,因此您可以将对象实例本身用作键(以及数字、字符串等)。
如果您想在 JavaScript 中做同样的事情,那将很困难,因为您必须生成自己唯一的对象 ID 并将它们附加到您想要跟踪的每个对象。有些人建议向 Object 类添加原型函数,但这会不必要地增加每个对象的开销。在任何情况下,您都希望通过函数调用为对象提供可跟踪的 ID,该函数调用将递增的静态数字分配给诸如“ __objectid__
”之类的唯一属性。
然后可以想象使用 Add(key,value) 之类的方法创建一个类似字典的类,但它必须将字符串、数字和对象存储在三个单独的内部散列中,以确保“3”不会与数字 3 或 id 为 3 的对象。 add 方法必须自动将 分配__objectid__
给尚未分配 id 的任何类型对象的键。即便如此,您也无法使用方括号访问字典,除非在 JavaScript 中存在一些我不知道的属性分配挂钩。
归档时间: |
|
查看次数: |
39514 次 |
最近记录: |