Javascript 作为对象键的函数与块中标记的函数之间的语法冲突
Javascript Conflicting Syntax Between Function As Object Key And Labeled Function in Block
假设您的浏览器同时支持labeled function declarations and block statements,那么浏览器确定以下是否是具有属性 名为[=14= 的对象的标准way/method 是什么? ] 即函数 F
,或包含标记为 L
:
的函数 F
的块
{
L: function F(){}
}
例如
为了说明我的意思,这里是上述代码的两个不同副本,修改后将其公开为数组和函数:
document.body.textContent = typeof( () => {
L: function F(){}
} )
在上面的代码中,浏览器识别箭头函数符号并确定它是一个块语句。然而,
document.body.textContent = typeof {
L: function F(){}
}
上面的代码让浏览器认为它是一个写成对象文字的对象,索引L
是函数F
嗯...我认为:
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' 索引的对象
您可以将问题简化为:浏览器如何知道 {
是否启动了 块 以及何时启动了 object literal?
答案是如果它出现在语句位置,JS 引擎会将 {
视为块的开始,如果出现在表达式位置,则将其视为对象文字的开始。
这就是为什么您必须在 {}
周围添加括号 (()
) 的原因,当它们出现在语句位置但您想要一个对象时。
标签函数声明的引入并没有改变任何情况,因为情况已经不明确了:
{
foo: 42
}
再看规范,其实指出了这个歧义:
An ExpressionStatement cannot start with a U+007B (LEFT CURLY BRACKET) because that might make it ambiguous with a Block.
(语法也反映了这一点)
假设您的浏览器同时支持labeled function declarations and block statements,那么浏览器确定以下是否是具有属性 名为[=14= 的对象的标准way/method 是什么? ] 即函数 F
,或包含标记为 L
:
F
的块
{
L: function F(){}
}
例如
为了说明我的意思,这里是上述代码的两个不同副本,修改后将其公开为数组和函数:
document.body.textContent = typeof( () => {
L: function F(){}
} )
在上面的代码中,浏览器识别箭头函数符号并确定它是一个块语句。然而,
document.body.textContent = typeof {
L: function F(){}
}
上面的代码让浏览器认为它是一个写成对象文字的对象,索引L
是函数F
嗯...我认为:
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' 索引的对象
您可以将问题简化为:浏览器如何知道 {
是否启动了 块 以及何时启动了 object literal?
答案是如果它出现在语句位置,JS 引擎会将 {
视为块的开始,如果出现在表达式位置,则将其视为对象文字的开始。
这就是为什么您必须在 {}
周围添加括号 (()
) 的原因,当它们出现在语句位置但您想要一个对象时。
标签函数声明的引入并没有改变任何情况,因为情况已经不明确了:
{
foo: 42
}
再看规范,其实指出了这个歧义:
An ExpressionStatement cannot start with a U+007B (LEFT CURLY BRACKET) because that might make it ambiguous with a Block.
(语法也反映了这一点)