为什么呢!{}[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 :