对象文字比较的奇怪行为

时间:2018-06-22 13:38:36

标签: javascript google-chrome

我已经搜索过,但找不到JavaScript后面的逻辑。

当我输入Chrome控制台时:

{} == null 

返回

  

未捕获的SyntaxError:意外令牌==

但是

{} == {}

{} == function(){} 

返回假

为什么?

4 个答案:

答案 0 :(得分:4)

我假设您了解为什么{} == null会抛出SyntaxError。长话短说,这是因为{在开始时开始一个语句块而不是对象文字。您可以查看答案here

{} == {}开始起作用的原因开始。

如果您在控制台中检查可评估表达式的铬代码。您可以找到以下(code

if (/^\s*\{/.test(text) && /\}\s*$/.test(text))
    text = '(' + text + ')';
executionContext.evaluate(text, "console", !!useCommandLineAPI, false, false, true, printResult);

此代码用括号将{} == {}代码包装起来,使其成为比较两个空对象文字的有效表达式({} == {})。因为对象是按引用进行比较的,所以它的值为false

节点repl具有相同的行为src

if (/^\s*\{/.test(code) && /\}\s*$/.test(code)) {
  // It's confusing for `{ a : 1 }` to be interpreted as a block
  // statement rather than an object literal.  So, we first try
  // to wrap it in parentheses, so that it will be interpreted as
  // an expression.
  code = `(${code.trim()})\n`;
  wrappedCmd = true;
}

答案 1 :(得分:1)

您可以在Statement(第12条)下的规范中找到它

12-声明

声明:
块。 VariableStatement
空声明
ExpressionStatement


第一个适用的规则是Block或Expression语句。所以我们需要看12.4。

在12.4中,规范明确指出表达式语句不能以{开头。

尽管我还没有找到使示例2成为表达式的原因,也许它是特定于实现的

12.4表达式语句

语法 ExpressionStatement: [lookahead∉{{,function}]表达式;

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

语义 产生ExpressionStatement:[lookahead∉{{,function}] Expression;评估如下:

让exprRef是评估Expression的结果。 返回(正常,GetValue(exprRef),空)。

答案 2 :(得分:0)

我会说这是一个解析问题,而不是逻辑问题。

在Chrome浏览器中,我观察到了行为。

在IE中,每当将{}(或似乎任何对象文字)放在==的LHS上时,我都会遇到语法错误。

在两个浏览器中,将()放在表达式固定的位置。或首先将对象分配给变量

var x = {}
x == null

在我看来,这似乎是解析中的错误。从学术的角度来看,这是否是正确的,将需要仔细研究规范和语法。实际的答案是,有足够简单的解决方法,最好的选择是不这样做。

答案 3 :(得分:-4)

这是因为JavaScript很烂 它不起作用的原因是 JavaScript采用比较从第一个对象获取的类型。

例如

3+”1” = 4 

但是

“3”+1 = 31

第一个示例将数字作为运算符,因为第一个对象是数字 第二个示例将字符串视为第一个对象,并将该操作视为字符串的串联。

例如 {}是一个对象,但不能将null转换为对象

它以另一种方式起作用,因为 {}可以表示为空对象。