在FF和Chrome的控制台中,{}被视为未定义,直到明确评估:
{}; // undefined ({}); // ▶ Object
实际上,它的定义不如未定义 – 这显然是不好的语法:
{} === undefined; // SyntaxError: Unexpected token === {}.constructor; // SyntaxError: Unexpected token .
但是,如果它在另一边,不是这样,这很好:
"[object Object]" == {}.toString(); // true
或者如果不是第一个表达式:
undefined + undefined; // NaN {} + undefined; // NaN undefined + {}; // "undefined[object Object]"
是什么赋予了?
解决方法
好的,这是我的答案.这里没有什么新鲜事我只是链接到ECMAScript规范的语法的一个漂亮的副本,并显示了一些生产,以显示“为什么”它解析它的方式.在任何情况下,根据JavaScript / ECMAScript语法规则,行为是明确的:{}根据其所在的“上下文”而不同地进行解析.
JavaScript REPLs(“控制台”)开始解析Statement
语法生成或“语句上下文”中的代码. (这实际上是一个谎言,它从程序或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并在评估时导致错误.在这种情况下,{}是一个“表达式上下文”.
在{} ===未定义的情况下,它被解析为{}; ===未定义,或BLOCK; BOGUS – > STMT; BOGUS,这是一个语法错误.但是,通过加括号,这会更改:({} === undefined)被解析为(EXPR === EXPR) – > (EXPR) – > EXPR – > STMT.
在{}“嗨”的情况下,它被解析为{}; “嗨”,或块; EXPR – > STMT; EXPR – > STMT; STMT是有效的语法,即使它是愚蠢的(在这种情况下是一元的).同样地,就像上面这样,“hi”{}把{}放入一个“表达式上下文”中,它被解析为EXPR EXPR – > EXPR – > STMT.
JavaScript控制台只显示最后一个语句的结果,对于一个空的{}块,它是“undefined”(对于“没有”,但不存在). (这可能因浏览器/环境而异,在这种情况下返回的内容,例如,最后一个ExpressionStatement?)
快乐的编码.