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

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

Tanto en Firefox 4 beta como en Chrome.Explique el comportamiento extraño de .call (falso)

Es como ... ¿cuándo es un booleano, no un booleano?

+0

¡Lo amo! WTF javascript ?! – Prestaul

+0

, así que supongo que la respuesta a mi pregunta de cierre es cuándo es un 'Boolean'. – Domenic

Respuesta

6

Parece ser que cuando un booleano primitiva se pasa como primer argumento a call o apply, es automático en caja en un objeto Boolean. Esto es claro en Firebug en Firefox 4:

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

En el inspector de Chrome, es confuso al principio, pero un poco de sondeo revela la verdad:

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

Todo JavaScript son "Truthy", incluso new Boolean(false) y new Number(0). Por lo tanto, al utilizar dos operadores de negación (el truco !!) los lanza a un booleano true.

4

Encontré esta línea en la especificación que explica el comportamiento.

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

Esencialmente el valor false será convertido a un objeto booleano. La primera aplicación del operador ! convertirá el objeto a true y luego invertirá a false. La segunda aplicación del operador ! invertirá false en true.

texto completo

 
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 
+0

Oooh Estoy realmente tentado de aceptar esta como la respuesta aceptada ya que hace referencia a la especificación ... pero la respuesta de ide fue bastante fácil de seguir, así que quiero mantenerla en la parte superior para cualquier otra persona que se encuentre con esto :). – Domenic

+0

@Domenic - Comprensible, si quieren profundizar un poco, todo lo que tienen que hacer es desplazarse hacia abajo un poco. – ChaosPandion