It depends in which syntactic position the parser is when you evaluate your expressions. Consider:
console.log(eval('{}+[]'), '==', eval('{}; +[]'))
console.log({}+[])
console.log('---')
console.log(eval('{}+[]+{}+[1]'), '==', eval('{}; +[] + {} + [1]'))
console.log({}+[]+{}+[1])
console.log('---')
console.log(eval('{}+[]+{}'), '==', eval('{}; +[] + {}'))
console.log({}+[]+{})
where "eval" blocks correspond to the "statement" position and bare "console.logs" are in the "expression" position. The leading {}
is only treated as a block in the statement position.
> let esprima = require('esprima');
undefined
> esprima.parse('{}+[]+{}')
Script {
type: 'Program',
body:
[ BlockStatement { type: 'BlockStatement', body: [] },
ExpressionStatement { type: 'ExpressionStatement', expression: [BinaryExpression] } ],
sourceType: 'script' }
> esprima.parse('( {}+[]+{} )')
Script {
type: 'Program',
body:
[ ExpressionStatement { type: 'ExpressionStatement', expression: [BinaryExpression] } ],
sourceType: 'script' }
>
Note that when you evaluate your tests directly in the console or repl, the behaviour may differ from platform to platform, because consoles/repls use different heuristics to decide whether your input is a statement or an expression. See this answer for examples.