Recientemente estaba comparando la versión actual de json2.js con la versión que tenía en mi proyecto y noté una diferencia en cómo se creaba y se ejecutaba la expresión de la función.
El código utilizado para envolver una función anónima entre paréntesis y luego ejecutarla,
(function () {
// code here
})();
pero ahora envuelve la función ejecutada automáticamente entre paréntesis.
(function () {
// code here
}());
Hay un comentario de CMS en la respuesta aceptada de Explicar la sintaxis de la función anónima encapsulada de JavaScript que "ambos: (function(){})();
y (function(){}());
son válidos".
Me preguntaba cuál es la diferencia. ¿El primero toma memoria al dejar una función global y anónima? ¿Dónde debería ubicarse el paréntesis?
javascript
syntax
anonymous-function
iife
Kevin Hakanson
fuente
fuente
Respuestas:
Son prácticamente iguales.
El primero envuelve una función entre paréntesis para convertirla en una expresión válida y la invoca. El resultado de la expresión no está definido.
El segundo ejecuta la función y los paréntesis alrededor de la invocación automática la convierten en una expresión válida. También se evalúa como indefinido.
No creo que haya una forma "correcta" de hacerlo, ya que el resultado de la expresión es el mismo.
fuente
+function(){}()
o!function(){}()
.-function(){}();
,!function(){}();
y básicamente cualquier otro operador justo antesfunction
también funciona, pero me quedaría con las versiones que usan parens). Veo el primero mucho más que el segundo, y es mi preferencia; para mí también tiene más sentido, pero eso es subjetivo. FWIW: jsbin.com/ejaqowEn ese caso, no importa. Está invocando una expresión que se resuelve en una función en la primera definición y definiendo e invocando inmediatamente una función en el segundo ejemplo. Son similares porque la expresión de la función en el primer ejemplo es solo la definición de la función.
Hay otros casos más obviamente útiles para invocar expresiones que se resuelven en funciones:
fuente
foo = function(){alert('hi');}
. ej ., si ninguna es una función, se genera un error.foo
es "veraz" pero no una función.No hay ninguna diferencia más allá de la sintaxis.
En cuanto a sus inquietudes sobre el segundo método para hacerlo:
Considerar:
(function namedfunc () { ... }())
namedfunc
aún no estará en el ámbito global aunque haya proporcionado el nombre. Lo mismo ocurre con las funciones anónimas. La única forma de conseguirlo en ese ámbito sería asignarlo a una variable dentro de los parens.Los parens externos son innecesarios:
Pero no querías esa declaración global de todos modos, ¿verdad?
Entonces se reduce a:
Y puede reducirlo aún más: el nombre es innecesario ya que nunca se usará (a menos que su función sea recursiva ... e incluso entonces podría usar
arguments.callee
)Esa es la forma en que lo pienso (puede que sea incorrecto, todavía no he leído la especificación ECMAScript). Espero eso ayude.
fuente
arguments.callee
está obsoleto desde ES5 (y prohibido en modo estricto).¡La diferencia simplemente existe porque a Douglas Crockford no le gusta el primer estilo para IIFE ! (en serio) ¡¡ Como puedes ver en este video !!.
La única razón para la existencia de la envoltura adicional
()
{en ambos estilos} es ayudar a hacer esa sección de código Function Expression , porque Function Declaration no se puede llamar inmediatamente. Algunas secuencias de comandos / Minify-ERS uso justo+
,!
,-
y~
en lugar de paréntesis, también. Me gusta esto:Y todos estos son exactamente los mismos que sus alternativas. La elección entre estos casos es completamente por su cuenta y no hace ninguna diferencia. {Las de
()
productos 1 byte del archivo más grande ;-)}fuente