博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

JS沙雕问题:为什么对象属性名可以使用保留字?

Posted on 2021-09-30 21:22  kpi311  阅读(115)  评论(0)    收藏  举报

0 tl;dr

直接看答案(stackoverflow)

1 问题来源

手写promise的时候突然被惊醒:promise凭什么能用catch做函数名啊?

不是说好变量名只能用非保留字,并且不以数字开头吗?

2 追问

于是直接百度。结果是明确的,当然百度不到。于是上谷歌用英文搜,果然早就有人在StackOverflow问了。不过提问者的出发点和我不同。

提问者想问的是:保留字作为对象属性名要不要加引号。

我想问的是:凭什么不用加引号保留字就可以作为属性名。因为我也知道,只要是字符串,无论什么内容都能做属性名。

算是殊途同归,卧龙凤雏吧。

3 解惑

上面的链接里说得非常详细。

简而言之,es5之前,确实是不能直接将保留字用作属性名的。一定要用只能用字符串配合中括号语法。

而es5之后,这个限制悄悄变了。

3.1 变量名的集合

ES的BNF把符号名划分成了几种集合:IdentifierNameReservedName以及Identifier

其中IdentifierReservedName没有交集,可以看作两者之间非此即彼,或者说互为补集。

ReservedName就包含了关键字、未来保留字、null、true和false。此外的合法变量名通通可以看作是Identifier的元素。

ReservedName以及Identifier都是IdentifierName的真子集。

3.2 对象字面量属性名的取值集合

ES5.1说明书中,对于一个对象字面量,属性名集合PropertyName定义了其取值范围:IdentifierNameStringLiteral以及NumericLiteral

带恶人找到了:IdentifierName。也就是说,ReservedNameIdentifier都可以用作对象的属性名。

而在ES3的说明书中,这个地方只能使用IdentifierStringLiteral以及NumericLiteral。不能使用ReservedName

4 总结

要不是脑袋搭错线我也不会想到这个问题,实在是太细了。

但是从另一个角度来看,其实我习以为常的定义并不能视作是毋庸置疑的结论,实际上问题往往就出在未经验证的先验知识上。