Please explain the strange behavior .call (false)

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

In the latest version of Firefox 4 and Chrome.

Is it like ... when is it logical, not logical?

+6
javascript boolean
source share
2 answers

It seems that when a primitive boolean is passed as the first argument to call or apply , it is automatically placed in a Boolean object. This is clear in Firebug on Firefox 4:

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

In the Chrome inspector, this is initially confusing, but a little research shows the truth:

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

All JavaScript objects are "true" , even new Boolean(false) and new Number(0) . Therefore, using two negation operators (trick !! ), they throw them into true boolean.

+6
source share

I found this line in the specification that explains the behavior.

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

Essentially false will be converted to a boolean. The first operator application ! converts the object to true and then inverts it to false . The second operator application ! inverts false to true .

Full text

  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 
+4
source share

All Articles