use*_*508 131 javascript
{}[true]是[true]和![true]应该的false.
那么为什么 !{}[true]评价true呢?
Fré*_*idi 172
我相信这是因为plain {}[true]被解析为一个空语句块(不是对象文字),后跟一个包含的数组true,即true.
在另一方面,在施加!操作者使解析器解释{}作为对象常量,所以下面{}[true]变得返回成员访问undefined,并且!{}[true]确实是true(作为!undefined是true).
doo*_*oxe 44
因为{}[true]不返回true,但是undefined,undefined被评估为false:
'use strict';
var b = {}[true];
alert(b); // undefined
b = !{}[true];
alert(b); // true
Run Code Online (Sandbox Code Playgroud)
Gam*_*iac 27
因为
{}[true]
Run Code Online (Sandbox Code Playgroud)
评估undefined,并且!undefined是true.
来自@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.对于那些需要进一步证据的人:

使用Firefox,它还评估为true:

Spu*_*ley 23
混淆的原因在于对您的第一个断言的误解:
{}[true] 是 [true]
你运行它时所看到的是模棱两可的结果.Javascript有一套定义的规则来处理如何处理这样的歧义,在这种情况下,它会将你看到的signle语句分解为两个单独的语句.
所以Javascript将上面的代码视为两个独立的陈述:首先,有一个{},然后有一个完全独立的[true].第二个陈述是给你结果的东西[true].第一个陈述{}完全被忽略了.
您可以通过尝试以下方法来证明这一点:
({}[true])
Run Code Online (Sandbox Code Playgroud)
即将整个事物包装在括号中以强制解释器将其作为单个语句读取.
现在你会看到你的陈述的实际价值是undefined.(这也有助于我们以后了解下一部分)
现在我们知道问题的最初部分是红鲱鱼,所以让我们转到问题的最后部分:
那么为什么!{} [true]评估为真?
在这里,我们有相同的声明,但!附加在它的前面.
在这种情况下,Javascript的规则告诉它将整个事物评估为单个语句.
请回顾一下当我们用括号括起前面的陈述时发生的事情; 我们得到了undefined.这一次,我们实际上在做同样的事情,但是把它!放在前面.因此,您的代码可以简化为!undefined,即true.
希望这能解释一下.
这是一个复杂的野兽,但这里要学到的教训是在控制台中评估它们时使用括号括起来,以避免这样的虚假结果.
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)
我们知道的!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;
}
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)=分组(未定义)=未定义发生这种情况是因为{}你的意思不是文字表示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)
{} 是一个没有属性的对象.[]紧跟在一个对象之后,它意味着"访问此名称的属性"而不是"创建一个数组"true是一个布尔值,但被用作属性名称,因此它被强制转换为字符串("true")true(因为它没有属性),所以{}['true']也是如此undefined!undefined强制转换undefined为布尔值(false)false了true.| 归档时间: |
|
| 查看次数: |
6360 次 |
| 最近记录: |