为什么呢!{}[true]在JavaScript中是否计算为true?

为什么呢!{}[true]在JavaScript中是否计算为true?,javascript,Javascript,{}[true]是[true]和![正确]应为false 那为什么!{}[true]求值为true?因为{}[true]不返回true,而是未定义的,并且未定义的求值为false: {}[true] -> [true] -> ![true] -> false 因为 {}[true] 计算结果为未定义,和!未定义的为真 来自@schlingel: true用作键,{}用作哈希映射。不存在键为true的属性,因此它返回undefined。不undefined是true,正如预

{}[true]
[true]
![正确]
应为
false


那为什么
!{}[true]
求值为
true

因为
{}[true]
不返回
true
,而是
未定义的
,并且
未定义的
求值为
false

{}[true] -> [true] -> ![true] -> false

因为

{}[true]
计算结果为
未定义
,和
!未定义的

来自@schlingel:

true
用作键,
{}
用作哈希映射。不存在键为
true
的属性,因此它返回
undefined
。不
undefined
true
,正如预期的那样

控制台会话(
[0.10.17]
):

但是,在控制台中:

因此,没有矛盾。您可能正在使用旧版本的JavaScript虚拟机。对于需要进一步证据的人:

更新 对于,它的计算结果也为
true


您没有反转它的值

![true] != [!true]
查看此链接:

  • {}
    是一个没有属性的对象
  • 由于
    []
    紧跟在对象之后,因此它的意思是“访问此名称的属性”,而不是“创建数组”
  • true
    是一个布尔值,但被用作属性名,因此它被转换为字符串(
    “true”
  • 对象没有名为
    true
    (因为它没有属性)的属性,因此
    {}['true']
    未定义的
  • !未定义的
    未定义的
    强制转换为布尔值(
    false
  • not运算符将
    false
    变为
    true

之所以发生这种情况,是因为您所指的
{}
不是
对象的字面表示,而是空范围(或空代码块):

它只计算范围内的代码,然后向您显示数组

从你的

!{}[true]
只需将此范围转换为int并返回相同的数组true。此代码中没有布尔检查

如果您试图检查
{}[true]
的结果,您将得到
false

{}[true] -> [true] -> ![true] -> false
因为没有更多的范围

所以
在您的问题中,执行与以下相同的操作:

!function() {
   //...
}

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


另一方面,应用
运算符使解析器将
{}
解释为对象文本,因此以下
{}[true]
成为返回
未定义的
的成员访问!{}[true]
确实是
true
(正如
!undefined
true
)。

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


{}[true]
[true]

当你运行它时,你看到的是模棱两可的结果。Javascript有一套定义好的规则来处理这样的歧义,在本例中,它将您所看到的单语句分解为两个单独的语句

因此Javascript将上述代码视为两个独立的语句:首先是一个
{}
,然后是一个完全独立的
[true]
。第二条语句是给出结果的内容
[true]
。第一条语句
{}
被有效地完全忽略

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

({}[true])
把整件事用括号括起来,迫使口译员把它当作一条语句来读

现在您将看到语句的实际值是
undefined
。(这也将有助于我们以后理解下一部分)

现在我们知道你问题的开始部分是一条红鲱鱼,所以让我们进入问题的最后部分:

那为什么呢!{}[true]计算为true

在这里,我们有相同的语句,但是有一个
附加到它的前面

在本例中,Javascript的规则告诉它将整个内容作为一条语句进行计算

回想一下,当我们把前面的语句用括号括起来时发生了什么;我们得到了
未定义的
。这一次,我们有效地做了同样的事情,但是放了一个
在它前面。因此,您的代码可以简化为
!未定义
,即
true

希望这能解释一点


这是一个复杂的问题,但这里要学习的是,在控制台中计算语句时,在语句周围使用括号,以避免出现类似这样的虚假结果。

{}[true]
未定义的。若要查找该问题,请编写以下内容:

a = {};
a[true] === undefined // true
或者简单地说:

({})[true] === undefined // true
我们知道,
!未定义的


发件人:

:

因此,基本上,它使用表达式对对象执行
调用。表达方式是:

with((window&&window.console&&window.console._commandLineAPI)|{}){

{}+{};//这里的答案很好,下面是伪代码的分解:

  • {}['whater']
    =空块,NewArray('whater')=NewArray('whater'))
  • {}[true]
    =空块,NewArray(true)=NewArray(true)
  • !{}['whatever']
    =LogicalNOT(convertToBool(NewObject.whatever))=LogicalNOT(convertToBool(未定义))=LogicalNOT(false)=true
  • ({}['whatever'])
    =分组(NewObject.whatever)=分组(未定义)=未定义
让我们再多玩一点! 首先,让我们玩一玩吧!:

//----------#01#-----------
{}[true]; //[true]

//----------#02#-----------
var a = {}[true]; 
      console.log(a); //undefined

//----------#03#-----------
{ b: 12345 }[true]; //[true]

//----------#04#-----------
{ b: 12345 }["b"]; //evaluates to ["b"] ?!?

//----------#05#-----------
{ b: 12345 }.b; // "Unexpected token ."

//----------#06#-----------
({ b: 12345 }).b; //12345

//----------#07#-----------
var c = { b: 12345 }.b; 
      console.log(c); //12345

//----------#08#-----------
var c = { b: 12345 }["b"];
      console.log(c); //12345

//----------#09#-----------
{ true: 54321 }[true]; // "SyntaxError: Unexpected token : "

//----------#10#-----------
var d = { true: 54321 }[true]; //No error here ¬¬
      console.log(d); //54321

//----------#11#-----------
!{}[true]; // true
for(var i=0; i < 1; i++){}function a(){};alert("Passed here!");if(true){}alert("Passed here too!")

好的,让我们试着一个接一个地理解这些疯狂的行为: 1)在这里,
{}
被解析为一个空代码块。没有赋值、求反、分组(带括号)或任何向p
({})[true] === undefined // true
  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;
  }
with ((window && window.console && window.console._commandLineAPI) || {}) {
    {}+{};// <-- This is your code
}
//----------#01#-----------
{}[true]; //[true]

//----------#02#-----------
var a = {}[true]; 
      console.log(a); //undefined

//----------#03#-----------
{ b: 12345 }[true]; //[true]

//----------#04#-----------
{ b: 12345 }["b"]; //evaluates to ["b"] ?!?

//----------#05#-----------
{ b: 12345 }.b; // "Unexpected token ."

//----------#06#-----------
({ b: 12345 }).b; //12345

//----------#07#-----------
var c = { b: 12345 }.b; 
      console.log(c); //12345

//----------#08#-----------
var c = { b: 12345 }["b"];
      console.log(c); //12345

//----------#09#-----------
{ true: 54321 }[true]; // "SyntaxError: Unexpected token : "

//----------#10#-----------
var d = { true: 54321 }[true]; //No error here ¬¬
      console.log(d); //54321

//----------#11#-----------
!{}[true]; // true
{ alert(123) }[true]
for(var i=0; i < 1; i++){}function a(){};alert("Passed here!");if(true){}alert("Passed here too!")
var obj = {if: 111, for: 222, switch: 333, function: 444, true: 555}
{a: 1, b: 2} //=>>>SyntaxError: Unexpected token :