为什么!{} [true]在JavaScript中评估为true?

use*_*508 131 javascript

{}[true][true]![true]应该的false.

那么为什么 !{}[true]评价true呢?

Fré*_*idi 172

我相信这是因为plain {}[true]被解析为一个空语句块(不是对象文字),后跟一个包含的数组true,即true.

在另一方面,在施加!操作者使解析器解释{}作为对象常量,所以下面{}[true]变得返回成员访问undefined,并且!{}[true]确实是true(作为!undefinedtrue).

  • @evilcandybag:绝对不是.`undefined`是假的(我们经常依赖的东西--`if(obj.maybeExists)...`),所以`!undefined`是真的,这是完全合乎逻辑的. (86认同)
  • 另一方面,!undefined为真的事实仍然是不可原谅的. (25认同)
  • @Josh,我认为evilcandybag在某些语言中更喜欢类似于`null`的行为,``undefined`等于`undefined`.但是在Javascript中并非如此. (8认同)
  • @Cruncher如果a未定义,并且b未定义,我们怎么可能知道a!= b?特别是当两个变量的唯一已知特征完全相同时. (7认同)
  • @evilcandybag:因此必须定义一些"未定义"(`!undefined`)的东西才符合逻辑.如果定义了某些东西,那么它通常被解释为"真实". (6认同)
  • @OozeMeister那太荒谬了.`一个= FALSE`.`a`是定义的,定义明确的,是错误的.假设a和b都是未定义的,但我们知道!= b.既然b未定义,那一定是真的吗?但是因为a未定义b必须是真的吗?但那不可能,因为a!= b.如果你只是假设一些未定义的东西,你会遇到完全矛盾. (2认同)
  • @fluffy,null绝对不是*对象.[link](http://stackoverflow.com/questions/3662952/is-null-an-object-in-javascript) [link](http://stackoverflow.com/questions/18808226/why-is-typeof- null-object/18808270)[link](http://stackoverflow.com/questions/801032/why-is-null-an-object-and-whats-the-difference-between-null-and-undefined).你在哪里可以评价为真? (2认同)

doo*_*oxe 44

因为{}[true]不返回true,但是undefined,undefined被评估为false:

http://jsfiddle.net/67GEu/

'use strict';
var b = {}[true];
alert(b); // undefined
b = !{}[true];
alert(b); // true
Run Code Online (Sandbox Code Playgroud)

  • 如果在控制台中评估`{} [true]`,则得到`[true]`,因为`{}`被解释为空代码块,而不是对象.这完全是关于`{}`的背景和模糊性. (21认同)
  • @ t.niese,因为它被解析为包含标签(`key:`)和字符串文字(`"value"`)的语句块,后跟一个数组.解析器仍然没有看到对象文字. (3认同)

Gam*_*iac 27

因为

{}[true]
Run Code Online (Sandbox Code Playgroud)

评估undefined,并且!undefinedtrue.

来自@schlingel:

true用作键和{}哈希映射.不存在具有键的属性,true因此它返回undefined.不undefined就是true,符合市场预期.

控制台会话(Node.js [0.10.17]):

> {}[true]
undefined
> !{}[true]
true
> [true]
[ true ]
> ![true]
false
>
Run Code Online (Sandbox Code Playgroud)

但是,在Google Chrome控制台中:

> !{}[true]
true
Run Code Online (Sandbox Code Playgroud)

所以,没有不一致.您可能正在使用旧版本的JavaScript VM.对于那些需要进一步证据的人:

在此输入图像描述

UPDATE

使用Firefox,它还评估为true:

在此输入图像描述

  • downvote的原因是什么?这个有8票的答案几乎完全相同,我得到了downvote?我做错了什么? (2认同)

Spu*_*ley 23

混淆的原因在于对您的第一个断言的误解:

{}[true][true]

你运行它时所看到的是模棱两可的结果.Javascript有一套定义的规则来处理如何处理这样的歧义,在这种情况下,它会将你看到的signle语句分解为两个单独的语句.

所以Javascript将上面的代码视为两个独立的陈述:首先,有一个{},然后有一个完全独立的[true].第二个陈述是给你结果的东西[true].第一个陈述{}完全被忽略了.

您可以通过尝试以下方法来证明这一点:

({}[true])
Run Code Online (Sandbox Code Playgroud)

即将整个事物包装在括号中以强制解释器将其作为单个语句读取.

现在你会看到你的陈述的实际价值是undefined.(这也有助于我们以后了解下一部分)

现在我们知道问题的最初部分是红鲱鱼,所以让我们转到问题的最后部分:

那么为什么!{} [true]评估为真?

在这里,我们有相同的声明,但!附加在它的前面.

在这种情况下,Javascript的规则告诉它将整个事物评估为单个语句.

请回顾一下当我们用括号括起前面的陈述时发生的事情; 我们得到了undefined.这一次,我们实际上在做同样的事情,但是把它!放在前面.因此,您的代码可以简化为!undefined,即true.

希望这能解释一下.

这是一个复杂的野兽,但这里要学到的教训是在控制台中评估它们时使用括号括起来,以避免这样的虚假结果.

  • 我不认为`{} [true]`是*无效*,只是*模棱两可*.它可以解释为"空代码块后跟数组文字"或"没有属性的对象文字,其中正在访问属性".我不知道第一个在技术上是否是ASI的情况(许多语言不会在那里放置一个分号)但是这是问题的核心 - 上下文敏感的解释. (2认同)

Ion*_*zău 14

{}[true]undefined.要找到这样写:

a = {};
a[true] === undefined // true
Run Code Online (Sandbox Code Playgroud)

或者干脆:

({})[true] === undefined // true
Run Code Online (Sandbox Code Playgroud)

我们知道的!undefinedtrue.


来自@Benjamin Gruenbaum的回答:

Chrome dveloper工具执行以下操作:

  try {
      if (injectCommandLineAPI && inspectedWindow.console) {
          inspectedWindow.console._commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
          expression = "with ((window && window.console && window.console._commandLineAPI) || {}) {\n" + expression + "\n}";
      }
      var result = evalFunction.call(object, expression);
      if (objectGroup === "console")
          this._lastResult = result;
      return result;
  } 
  finally {
      if (injectCommandLineAPI && inspectedWindow.console)
          delete inspectedWindow.console._commandLineAPI;
  }
Run Code Online (Sandbox Code Playgroud)

所以基本上,它call使用表达式对对象执行.表达式为:

with ((window && window.console && window.console._commandLineAPI) || {}) {
    {}+{};// <-- This is your code
}
Run Code Online (Sandbox Code Playgroud)

因此,正如您所看到的,表达式是直接评估的,没有包装括号.

可以在此问题中找到更多信息.


Ben*_*esh 10

这里的答案很好,这里是伪代码的细分:

  • {}['whatever'] =空块,NewArray('无论')= NewArray('无论')
  • {}[true] =空块,NewArray(true)= NewArray(true)
  • !{}['whatever'] = LogicalNOT(convertToBool(NewObject.whatever))= LogicalNOT(convertToBool(undefined))= LogicalNOT(false)= true
  • ({}['whatever']) =分组(NewObject.whatever)=分组(未定义)=未定义


ant*_*rat 8

发生这种情况是因为{}你的意思不是文字表示Object,而是空范围(或空代码块):

{ var a = 1 }[true] // [true] (do the same thing)
Run Code Online (Sandbox Code Playgroud)

它只是评估范围内的代码,然后显示您的数组.

从你的

!{}[true]
Run Code Online (Sandbox Code Playgroud)

只需将此范围转换为int并返回相同的数组即可.此代码中没有bool检查.

如果你试图查看{}[true]你的结果,你会得到false:

{}[true] -> [true] -> ![true] -> false
Run Code Online (Sandbox Code Playgroud)

因为没有任何范围.

所以!在你的问题中做同样的事情:

!function() {
   //...
}
Run Code Online (Sandbox Code Playgroud)


Que*_*tin 6

  • {} 是一个没有属性的对象.
  • 由于[]紧跟在一个对象之后,它意味着"访问此名称的属性"而不是"创建一个数组"
  • true是一个布尔值,但被用作属性名称,因此它被强制转换为字符串("true")
  • 该对象没有被调用的属性true(因为它没有属性),所以{}['true']也是如此undefined
  • !undefined强制转换undefined为布尔值(false)
  • not运算符变成falsetrue.

  • 在`{} [true]`(没有其他上下文)的情况下,`{}`是*不是*没有属性的对象,它是一个空代码块. (2认同)

归档时间:

查看次数:

6360 次

最近记录:

11 年,9 月 前