Sé que la forma típica de un IIFE es:
(function(){/* code */})()
Sin embargo, recientemente encontré uno nuevo:
!function(){/* code */}() +function(){/* code */}()
que también funcionan como IIFE.
creo que en el primero !
hace que el valor sea booleano, por lo que el código es equivalente a true()
, y en el segundo +
hace que el valor sea un número, por lo que el código es el mismo que NaN()
? Pero true()
y NaN()
no pueden funcionar, mientras que las dos formas anteriores funcionan bien.
¿Cómo funcionan esas dos formas de IIFE?
En los casos de !function() {}()
y +function() {}()
, JavaScript primero evaluará el lado derecho de la declaración/IIFE dada y luego convertirá el valor de retorno de IIFE en un valor booleano en caso de !
o para escribir número en caso de +
. Si el IIFE devuelve un valor booleano !
negará el valor de retorno.
console.log( !function() { return "something"; }() ); /** !function() { return "something"; }() evaluates to !"something" and not true() or false() lastly !"something" is equivalent to false */
Hay muchas formas de hacer que una función se ejecute inmediatamente después de su definición. Lo común es que debe asegurarse de que la función no se interprete como una declaración de función, sino como una expresión de función.
Al anteponer la palabra clave de función con un operador unario como !
o +
o cualquier otro operador unario ( ~
, -
, void
, ...etc) evitas que la function
se interprete como una declaración .
También la asignación funcionará:
var x = function(){/* code */}()
O matriz literal:
[function(){/* code */}()]
O pasándolo como argumento a una función (barata):
Object(function(){/* code */}())
O aplicando un operador binario, siempre que la expresión de la función sea el segundo operando y no el primero. Aquí con el operador coma:
0,function(){/* code */}()
La palabra clave function
tiene un propósito dual. Dependiendo del contexto en el que lo use, inicia una declaración de función o una expresión de función.
Las declaraciones de función declaran una variable local (elevada) en el ámbito de la función actual y asignan la función a esa variable.
Las expresiones de función no lo hacen, requieren que haga algo con la función inmediatamente. Los ejemplos comunes incluyen asignarlo a una propiedad de un objeto, pasarlo como argumento a una función (es decir, convertirlo en una devolución de llamada) o usarlo como un IIFE.
Si intenta seguir una declaración de función con ()
, se producirá un error.
function myFunction() { console.log("Example"); }();
Solo las expresiones de función se pueden invocar inmediatamente como expresiones de función. (Bueno, las funciones de flecha también pueden hacerlo, pero los IIFE son mucho más antiguos que ellos).
Entonces, para usar un IIFE, debe hacer algo para cambiar el contexto en el que aparece la palabra clave de function
para que se use para crear una expresión en lugar de una declaración.
La forma clásica es envolver la función entre paréntesis.
(function myFunction() { console.log("Example"); })();
Pero cualquier cosa que lo convierta en una expresión funcionará.
Poner un operador (como !
o +
) delante de la palabra clave de function
hará eso.
mientras !
tomará el valor de retorno de llamar al IIFE y lo convertirá en un booleano negado y +
lo convertirá en un número que no es el punto . No hay nada a la izquierda del operador, por lo que ese valor se descarta.
Es solo una forma de hacer que la palabra clave de function
cree una expresión de función que se puede convertir en un IIFE.
Tenga en cuenta que los beneficios clave de los IIFE también los proporcionan las variables de ámbito de bloque ( let
y const
) y los módulos de JavaScript, por lo que no hay muchas razones para usar un IIFE en absoluto en 2022.