js中以块语句开头的对象强制

时间:2019-04-11 09:52:36

标签: javascript

所以,有一件事我无法理解。

我对此毫无疑问:

{}+[]+{}+[1]

给予

"0[object Object]1"

我真正不明白的是为什么

{}+[]+{}

给予

"[object Object][object Object]"而不是"0[object Object]"

我的理解是第一个{}是一个块语句,因此被忽略。然后,我们确实有+[]+{}的结果是"0[object Object]"

我在这里想念什么?

编辑: 尽管主题相同,但另一个问题没有提及{}被控制台解释为块代码或对象的区别。

1 个答案:

答案 0 :(得分:6)

这取决于解析器在评估表达式时所处的语法位置。考虑:

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({}+[]+{})

其中“ eval”块对应于“ statement”位置,裸露的“ console.logs”位于“ expression”位置。前导{}仅在语句位置视为一个块。

> 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' }
> 

请注意,当您直接在控制台或repl中评估测试时,平台之间的行为可能会有所不同,因为控制台/ repls使用不同的试探法来确定您的输入是语句还是表达式。有关示例,请参见this answer