2011-02-02 118 views
6
> (function() { return this; }).call(false) 
false 

> !!(function() { return this; }).call(false) 
true 

在Firefox 4测试版和Chrome最新版本中。请解释.call(false)的奇怪行为

这就像...什么时候是布尔值而不是布尔值?

+0

我喜欢它! WTF的JavaScript?! – Prestaul 2011-02-02 19:35:30

+0

所以我想我的结束问题的答案是什么时候它是`布尔`。 – Domenic 2011-02-02 20:47:40

回答

6

似乎是,当原始布尔值被作为第一个参数,以callapply通过,它是自动盒装入Boolean对象。这是在Firebug明确在Firefox 4:

>>> (function() { return this; }).call(false) 
Boolean {} 

在Chrome的检查,这是最初混乱,但有点探测揭示了一个道理:

>>> (function() { return this; }).call(false) 
false 
>>> typeof (function() { return this; }).call(false) 
"object" 

所有的JavaScript对象是 “truthy”,甚至new Boolean(false)new Number(0)。因此,使用两个否定运算符(!!技巧)将它们转换为true布尔值。

4

我在解释行为的规范中找到了这条线。

 
3. Else if Type(thisArg) is not Object, set the 
    ThisBinding to ToObject(thisArg). 

本质上false值将被转换成布尔对象。 !运算符的第一个应用程序将把对象转换为true,然后转换为false!运营商的第二个应用会将false转换为true

全文

 
10.4.3 Entering Function Code 

The following steps are performed when control enters the 
execution context for function code contained in function 
object F, a caller provided thisArg, and a caller provided argumentsList: 

1. If the function code is strict code, set the ThisBinding to thisArg. 
2. Else if thisArg is null or undefined, 
    set the ThisBinding to the global object. 
3. Else if Type(thisArg) is not Object, set the 
    ThisBinding to ToObject(thisArg). 
4. Else set the ThisBinding to thisArg. 
5. Let localEnv be the result of calling NewDeclarativeEnvironment 
    passing the value of the [[Scope]] internal 
    property of F as the argument. 
6. Set the LexicalEnvironment to localEnv. 
7. Set the VariableEnvironment to localEnv. 
8. Let code be the value of F‘s [[Code]] internal property. 
9. Perform Declaration Binding Instantiation using the function code 
    code and argumentsList as described in