【问题标题】:Defining a JavaScript object in console在控制台中定义一个 JavaScript 对象
【发布时间】:2012-02-23 07:46:09
【问题描述】:

当我在 Chrome JavaScript 控制台中输入简单对象时,我会得到如下输出:

>true
true
>1/3
0.3333333333333333

等等。

但是当我键入对象时出现语法错误:

>{ a: 1, b: 2 }
SyntaxError: Unexpected token :
arguments: Array[1]
0: ":"
length: 1
__proto__: Array[0]
get message: function getter() { [native code] }
get stack: function getter() { [native code] }
set message: function setter() { [native code] }
set stack: function setter() { [native code] }
type: "unexpected_token"
__proto__: Error

虽然我确信这个表达式可以正确地用于初始化对象,因为:

>obj = { a: 1, b: 2 }
Object
a: 1
b: 2
__proto__: Object

也许这是一个愚蠢的问题,但我真的很想知道为什么会这样?

【问题讨论】:

  • 我知道的足以告诉你,这是因为 JavaScript 非常注重什么是有效表达式,什么不是。例如,function foo(){}函数声明,而(function foo(){})函数表达式,由于语法规则,它们具有不同的函数含义。我对规范的了解不足以为您指出不允许 {} 作为表达式但允许 ({}) 的确切措辞(试试看!),但我知道规范的疯狂程度足以告诉您该答案很可能只是让你说“嗯。好吧。”。
  • 您可能得到的最佳答案类似于+[] 等于0,但+[]+[] 等于字符串"0"原因。原因是“因为这是规范要求做的”,而没有深入了解为什么规范作者选择做出该决定。
  • 有趣的是,只输入{a:1} 会得到1,这也是因为对这种情况的不同解释。一个很好的答案可能还包括为什么会这样。如果按照我们的预期解释这个表达式,一个史诗般的答案会显示可能会发生什么混乱/冲突。
  • 除非我在对象后添加索引,否则无法重现此问题,如 stackoverflow.com/questions/48548444/… 自 2012 年以来控制台解析器是否已更改?
  • 是的,它已经改变了:stackoverflow.com/a/36438289/864233

标签: javascript json oop google-chrome v8


【解决方案1】:

因为您的语句被评估为block,而不是对象文字声明。

请注意,ExpressionStatement 不能以左大括号开头,因为这可能会使它与 Block 产生歧义。此外,ExpressionStatement 不能以 function 关键字开头,因为这可能会使其与 FunctionDeclaration 产生歧义。

要使其评估为 表达式,它需要位于赋值的右侧,用括号括起来或前面有一个运算符。 (!{a:1,b:2})

【讨论】:

  • !{a:1} 在你想要价值时并没有真正的帮助;)
  • @minitech:不,但它确实强制表达式评估。作为实际应用,您可以使用该属性从自执行函数中删除一个字节:!function(){...}(); 而不是传统的 (function(){...})();
【解决方案2】:
 { a: 1, b: 2 }

是一个代码块,有两个错误的labelled变量。

要创建一个对象,请将代码块用圆括号括起来,以便将大括号解释为对象字面量:

({ a: 1, b: 2 })

【讨论】:

  • 有趣的是,带标签的变量可以工作。问题出在逗号,如果您将其更改为分号,它也可以工作。奇怪的。你也可以在 JavaScript 中嵌入 URL...
【解决方案3】:

这是因为没有上下文的开头{ 被解释为块的开头。您可以使用括号:

({ a: 1, b: 2 })

尽管如此,它只是一个执行块——就像在iffor 之后可能会发现的那样。所以你可以输入:

{alert("Hello!");}

Here's more about that. 也阻止返回值,这既棒又令人失望。

【讨论】:

    【解决方案4】:

    因为{ a: 1, b: 2 } 不是要执行的有效表达式。 JavaScript 看起来像一段代码,因为它以花括号开头和结尾。

    如果您尝试({ a: 1, b: 2 }),它会起作用。

    【讨论】:

      【解决方案5】:

      因为您的语句被评估为一个块,而不是一个对象字面量声明。

      真正的乔什

      如果您希望将其作为对象进行评估,只需编写:

      > ({a : 1, b : 2})
      Object
      a: 1
      b: 2
      __proto__: Object
      

      【讨论】:

        【解决方案6】:

        试试这个:

        ({ "a" : 1, "b" : 2 })
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-02
          • 1970-01-01
          • 1970-01-01
          • 2015-01-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多