作为对象键的函数与块中的标记函数之间的Javascript语法冲突
Posted
技术标签:
【中文标题】作为对象键的函数与块中的标记函数之间的Javascript语法冲突【英文标题】:Javascript Conflicting Syntax Between Function As Object Key And Labeled Function in Block 【发布时间】:2017-06-15 21:01:04 【问题描述】:假设您有一个同时支持labeled function declarations 和block statements 的浏览器,浏览器确定以下是否为具有名为L
的属性的对象的标准方式/方法是函数F
,或包含函数F
的块标记为L
:
L: function F()
例如
为了公开我的意思,这里是上述代码的两个不同副本,经过修改以将其公开为数组和函数:
document.body.textContent = typeof( () =>
L: function F()
)
在上面的代码中,浏览器识别箭头函数符号并确定它是一个块语句。然而,
document.body.textContent = typeof
L: function F()
上面的代码让浏览器认为它是一个写成对象字面量的对象,索引L
是函数F
【问题讨论】:
【参考方案1】:您可以将问题简化为:浏览器如何知道 是否启动块以及何时启动对象字面量?
答案是,如果 出现在语句位置,JS 引擎会将其视为块的开始,如果它位于表达式位置,则将其视为对象字面量的开始。
这就是为什么当 出现在语句位置但您想要一个对象时,您必须在它们周围添加括号 (
()
)。
标签函数声明的引入根本没有改变情况,因为情况已经很模糊:
foo: 42
再看spec,其实是指出了这个歧义:
ExpressionStatement 不能以 U+007B(左大括号)开头,因为这可能会使其与 Block 混淆。
(语法也反映了这一点)
【讨论】:
能否请您在标准中说明这一点的地方添加引文。 (我完全同意这一点,但我仍然对血腥细节感到好奇) 规范中没有这样写,但它遵循语法规则:ecma-international.org/ecma-262/7.0/…。 解析器只是尝试匹配规则。在顶部你有一个 Script,它有一个 ScriptBody,它有一个 Statement 列表等 箭头符号是一个例外。例如,使用箭头符号,如果() => 3
创建一个返回 3 的函数,那么逻辑上() => L: function F()
应该创建一个返回一个对象的函数。但这不是这种方式,这意味着它必须更复杂。
没有那么复杂,但是是的,箭头函数还有额外的规则:ecma-international.org/ecma-262/7.0/…。正文可以是不以
开头的表达式,也可以是
,后跟语句列表,然后是
。【参考方案2】:
嗯...我认为:
if(1) // the brackets here belong to the if statement == block
L: function F()
在这里:
console.log( // the brackets represent JSON (javascript object notation)
L: function F()
)
这确实是一个带有“L”索引的对象
【讨论】:
这不能回答问题。你刚刚重述了这些例子。您似乎没有列出任何有关浏览器如何区分它们的信息(在代码的第一个 sn-p 中)。 我同意上面的答案更详细以上是关于作为对象键的函数与块中的标记函数之间的Javascript语法冲突的主要内容,如果未能解决你的问题,请参考以下文章
GraphQL 错误“字段必须是以字段名称作为键的对象或返回此类对象的函数。”
错误:对象作为 React 子对象无效(找到:带键的对象..........)