Хорошо, вот мой ответ. Здесь нет ничего нового. Я просто ссылаюсь на (симпатичную копию) спецификации ECMAScript для грамматики и показываю несколько произведений, чтобы показать, «почему» она анализирует так, как это делает. В любом случае, поведение четко определено в соответствии с правилами грамматики JavaScript / ECMAScript: {}
анализируется по-разному в зависимости от "контекста", в котором он находится.
JavaScript REPL s («консоли») начинает анализировать код в Statement
грамматическом производстве или «контексте оператора». (На самом деле это ложь, она начинается с производства Program
или SourceElements
, но это добавляет дополнительные конструкции, чтобы копаться в них.) Вот грубая грамматическая разбивка с упрощениями и упущениями; см. ссылку выше для получения дополнительной информации:
Statement
Block
...
ExpressionStatement
Block
# This is actually { StatementList[optional] }, but this is what
# it amounts to: * means "0 or more".
{ Statement* }
ExpressionStatement
# An ExpressionStatement can't start with "{" or "function" as
# "{" starts a Block and "function" starts a FunctionStatement.
[lookahead ∉ {{, function}]Expression ;
Expression
# This is really PrimaryExpression; I skipped a few steps.
...
( Expression )
Таким образом (в «контексте оператора»):
{}
-> Block # with no StatementList (or "0 statements")
-> Statement
И
({})
-> (Expression)
-> Expression
-> ExpressionStatement # omitted in productions below
-> Statement
Это также объясняет, почему undefined === {}
анализируется как EXPR === EXPR -> EXPR -> STMT
и приводит к ложному при оценке. {}
в этом случае находится в «контексте выражения».
В случае {} === undefined
он анализируется как {}; === undefined
или BLOCK; BOGUS -> STMT; BOGUS
, что является синтаксической ошибкой. Однако с добавлением скобок это меняется: ({} === undefined)
анализируется как (EXPR === EXPR) -> (EXPR) -> EXPR -> STMT
.
В случае {} + "hi"
он анализируется как {}; + "hi"
или BLOCK; + EXPR -> STMT; EXPR -> STMT; STMT
, что является допустимым синтаксисом, даже если он глупый (+
в данном случае унарный). Аналогично, как и выше, "hi" + {}
помещает {}
в "контекст выражения" и анализируется как EXPR + EXPR -> EXPR -> STMT
.
Консоль JavaScript просто показывает результат последнего оператора, который является «неопределенным» (ну, на самом деле, «ничем», но его не существует) для пустого блока {}
. (Это может варьироваться в зависимости от браузера / среды относительно того, что возвращается в этом случае, например, только последнее ExpressionStatement?)
Удачного кодирования.