Assuming you have a browser that supports both labeled function declarations and block statements, what is the standard way/method for browsers to determine if the following is an object with a property named L
that is function F
, or a block that contains function F
labeled as L
:
{
L: function F(){}
}
E.g.
To expose what I mean, here are two different copies of the above code modified to expose it as an array and as a function:
document.body.textContent = typeof( () => {
L: function F(){}
} )
In the above code, the browser recognizes the arrow function notation and determines that it is a block statement. However,
document.body.textContent = typeof {
L: function F(){}
}
The above code makes the browser think that it is an object written out as an object literal with index L
being function F
You can reduce the question to: How does the browser know whether {
starts a block and when does it start an object literal?
And the answer to that is that JS engines will treat {
as the start of a block if it appears in a statement position and as the start of an object literal if it is in an expression position.
That's the reason why you have to add parenthesis (()
) around {}
when they appear in a statement position but you want an object instead.
The introduction of labeled function declarations doesn't change the circumstances at all because the situation was already ambiguous:
{
foo: 42
}
Looking at the spec again, this ambiguity is actually pointed out:
An ExpressionStatement cannot start with a U+007B (LEFT CURLY BRACKET) because that might make it ambiguous with a Block.
(and the grammar reflects that too)
Well... I think that:
if(1){ // the brackets here belong to the if statement == block
L: function F(){}
}
While here:
console.log({ // the brackets represent JSON (javascript object notation)
L: function F(){}
})
This is indeed an object with 'L' index