I generate  AST  from  {} + {}  as follows 
{
  "type": "Program",
  "start": 0,
  "end": 5,
  "body": [
    {
      "type": "BlockStatement",
      "start": 0,
      "end": 2,
      "body": []
    },
    {
      "type": "ExpressionStatement",
      "start": 2,
      "end": 5,
      "expression": {
        "type": "UnaryExpression",
        "start": 2,
        "end": 5,
        "operator": "+",
        "prefix": true,
        "argument": {
          "type": "ObjectExpression",
          "start": 3,
          "end": 5,
          "properties": []
        }
      }
    }
  ],
  "sourceType": "module"
}
 from  AST , the first  {}  is still converted into a code block, and  +  is a unary operator, but geese are indeed treated as arithmetic operators  "[object Object] [object Object]"  in the expression of  chrome , which may be a feature of  chrome  (nonsense, I don't know why), in  firefox 
 the following is  you don't know the JavaScript (medium volume)  Chapter 5 P102 original text: 
< hr >
 there is another pit that is often mentioned (involving forced type conversion, see Chapter 4): 
 [] + {}; // "[object Object]"
 {} + []; // 0
  on the surface, the + operator produces different results depending on the first Operand ([] or {}), but it is not. In the first line of code, {} appears in the + operator expression, so it is treated as a value (empty object) . Chapter 
 4 mentioned that  [] will be cast to "" and {} will be cast to "[object Object]" . 
 but in the second line of code,  {} is treated as a separate empty code block (nothing is done) . There is no need for a semicolon at the end of the code block, so there is no syntax problem here. Finally,  + [] explicitly cast  (see Chapter 4) to 0. 
< hr >
 this series covers all the messy problems in  js  in great detail 
  because you wrote {} + {} in parentheses 
 