2011-05-09 13 views
52

Ambos bloques de código debajo alerta foo luego bar. La única diferencia es })() y }()).Son "(función() {})()" y "(función() {}())" funcionalmente iguales en JavaScript?

Código 1:

(function() 
{ 
    bar = 'bar'; 
    alert('foo'); 
})(); 

alert(bar); 

Código 2:

(function() 
{ 
    bar = 'bar'; 
    alert('foo'); 
}()); 

alert(bar); 

Entonces, ¿hay alguna diferencia, aparte de la sintaxis?

+1

ver también [Localización de paréntesis para funciones de JavaScript en el anonimato de auto-ejecución?] (Http://stackoverflow.com/questions/3384504/location-of-parenthesis-for-auto-executing-anonymous-javascript-functions) o [¿Hay una diferencia entre (función() {...}()); y (function() {...})();?] (http://stackoverflow.com/questions/3783007/is-there-a-difference-between-function-and-function) – Bergi

+1

justo cuando lo piensas todo en JS no es lo que esperas, lo es. engañado de nuevo! js primer idioma para usar pschology inversa !!! –

Respuesta

58

No; que son idénticos


Sin embargo, si se agrega new de antemano y .something después, van a ser diferentes.

Código 1

new (function() { 
    this.prop = 4; 
})().prop; 

Este código crea una nueva instancia de la clase de esta función, entonces se obtiene la propiedad prop de la nueva instancia.
Devuelve 4.

Es equivalente a

function MyClass() { 
    this.prop = 4; 
} 
new MyClass().prop; 

Código 2

new (function() { 
    return { Class: function() { } }; 
}()).Class; 

Este código llama new en la propiedad Class.
Dado que los paréntesis para la llamada de función están dentro del conjunto externo de paréntesis, no son recogidos por la expresión new, y en su lugar llaman a la función normalmente, devolviendo su valor de retorno.
La expresión new analiza hasta el .Class y crea una instancia de eso. (Los paréntesis después new son opcionales)

Es equivalente a

var namespace = { Class: function() { } }; 

function getNamespace() { return namespace; } 

new (getNamespace()).Class; 
//Or, 
new namespace.Class; 

Sin los paréntesis alrededor de la llamada a getNamespace(), esto se analiza como (new getNamespace()).Class — sería llamar a una instancia de la clase getNamespace y devolver la propiedad Class de la nueva instancia.

+1

Los ejemplos 'nuevos ... de apoyo' son útiles. Gracias. –

+1

De nada. – SLaks

+1

También hay una diferencia siempre que esté directamente precedida por un identificador, lo que podría ocurrir por accidente si no usa puntos y comas en su JavaScript. 'a (function() {return 5;}())' reduce a 'a (5)' mientras que a (function() {return 5;})() 'reduce a' a()() 'que reduce a '5()', que es ilegal. – Keen

6

No hay diferencia. Ambas son expresiones de funciones.

No es ser una tercera vía, también:

+function() { 
    bar = 'bar'; 
    alert('foo'); 
}(); 

(en lugar de la + otro operador podría funcionar, también)

La forma más común es

(function() { 
    // ... 
})(); 

sin embargo.

+2

http://jsperf.com/self-invoking-function –

+1

El nombre "función de invocación automática" es engañoso, ya que la función no se invoca recursivamente en su cuerpo, pero se invoca * siendo * inmediatamente después de la definición. Prefiero llamarlo "función invocada inmediatamente". – SasQ

7

No hay diferencia - la llave de apertura sólo sirve como un indicio sintáctica a comunicar al analizador que lo que sigue es una expresión función en lugar de una declaración función.

Cuestiones relacionadas