在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]"
是什么给出了?
答案 0 :(得分:10)
如果你自己使用花括号,它不是一个对象文字,它是一个代码块。由于代码块不包含任何代码,因此对其进行评估会产生undefined
。
答案 1 :(得分:6)
好的,这是我的答案。这里没有什么新东西。我只是链接到语法的ECMAScript规范(的一个漂亮的副本),并显示一些产品,以显示它解析它的方式“为什么”。在任何情况下,根据JavaScript / ECMAScript语法规则明确定义行为:{}
根据其所处的“上下文”进行不同的解析。
JavaScript REPL(“控制台”)开始解析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控制台只是显示最后一个Statement的结果,对于空{}
块,它是“未定义的”(好吧,“没有”,但不存在)。 (在这种情况下,浏览器/环境之间可能会有所不同,例如最后一个ExpressionStatement?)
快乐的编码。
答案 2 :(得分:2)
如果您只是在任何控制台中输入{}
作为输入,那么除了它的位置之外,没有任何上下文可以解释您希望花括号的含义。鉴于控制台的每个输入都被解释为新的代码行,开放大括号被视为新块的开始。结束}
在语法上是正确的,因为在这样的情况下经常使用空块:
try
{
//something
}
catch(e)
{}//suppress error
因此{}
在左侧总是未定义,并且从不吐出错误,因为空块是有效代码。
答案 3 :(得分:1)
当表达式以{
开头时,似乎两个控制台都将其视为一种模糊的条件。也许它被视为一个虚拟块。
试试这个:
{} // undefined
undefined === {} // false
使用{}
作为右手表达式可消除歧义。
您还可以从以下地址看到:
{a:42} // 42
{{a:42}} // 42
{{{a:42}}} // 42
外括号实际上被视为虚拟块。
这似乎不是一个控制台功能。甚至eval
也会这样对待他们,暗示你在控制台中输入的内容实际上的评估方式与传递给eval
的方式相同:
eval("{}") // undefined
eval("{alert(42)}") // alerts 42
答案 4 :(得分:0)
问题在于,在某些情况下,javascript会将{和}视为打开和关闭/ block /。而在其他情况下,{}是一个对象。案件确实取决于具体情况。
答案 5 :(得分:0)
答案 6 :(得分:0)
Javascript将语句和表达式的概念分开(C ++或Java等语言也是如此)。
例如if ...
是一个语句,x?y:z
是一个表达式。
表达式有值,声明没有。
Javascript语法的一个问题是{}
可以是表达式(在这种情况下,它表示空对象构造函数)或语句(在这种情况下,它表示空代码块...基本上一个NOP)所以如何解释它取决于上下文。