javascript function iife

javascript - ¿Cuáles son las diferentes formas de escribir un IIFE? ¿Cuáles son sus casos de uso?



function (2)

¿Por qué hacer esto?

Antes de llegar a la lista, comencemos con "¿Por qué hacer esto?"

La respuesta es: para mantener privadas las variables y las declaraciones de funciones dentro de la función. Por lo general, esto es para evitar los globales (evitar los globales es una buena idea TM ). P.ej:

+function() { function foo() { /* ... */ } foo(); var answer = 42; }();

Gracias al IIFE (llamado función de alcance en este contexto), foo y answer no son globales. Son privados del código dentro de la función, a menos que se exporten de alguna manera.

Puede hacerlo incluso si no tiene un alcance global, solo para evitar contaminar el alcance en el que se encuentre.

Los IIFE en general tienen otros usos, pero el estilo que ha citado generalmente se usa para determinar el alcance.

Los ejemplos

El autor está exagerando dramáticamente el caso de que "cada uno tiene sus propias cualidades y ventajas únicas".

A menos que esté utilizando el valor de retorno, todos son exactamente iguales:

!function (){}() ~function (){}() +function (){}() -function (){}() 1,function (){}() 1&&function (){}()

El código dentro de ellos se ejecuta, dentro del alcance de la función.

También podemos agregarlos a esa lista:

(function(){}()) (function(){})() 0||function (){}() 1^function(){}() // any binary math operator in place of ^ also works

Por supuesto, el 1 en todo lo anterior no es especial. Podría ser cualquier número (o casi cualquier otra cosa) para la mayoría de ellos, pero el que usa && no funcionaría con 0 "" , "" null , undefined , NaN o false (la función no se ejecutaría). Del mismo modo, el que tiene 0||... funciona siempre que el valor inicial sea falsey.

En este:

var i=function (){}()

... la única diferencia es que declara una variable, i , que almacena el valor de retorno. Eso puede, por supuesto, ser una gran diferencia. Considere esta versión más obvia:

var MyPseudoNamespace = function() { // ... return { /* nifty "namespace" stuff here */ }; })();

Finalmente:

new function (){}

Eso crea un nuevo objeto y luego llama a la función con this conjunto al nuevo objeto. Si no usa this dentro de la función, no tiene sentido. Si lo hace, bueno, si es útil depende de lo que haga con this .

Nota: Si existe alguna posibilidad de que el código que no controla llegue inmediatamente antes de su función de alcance (cuando combina y minimiza archivos, por ejemplo), es mejor comenzar todo esto con un ; , p.ej:

;!function (){}() ;~function (){}() ;+function (){}() ;-function (){}() ;1,function (){}() ;1&&function (){}() ;(function(){}()) ;(function(){})() ;0||function (){}() ;1^function(){}() // any binary math operator in place of ^ also works

Varios de ellos técnicamente no necesitan uno, pero la mayoría sí. Los efectos secundarios de no tenerlos pueden ser sutiles o catastróficos. Considerar:

Código antes de su código:

obj.prop = function() { // Do something big and awful }

Entonces tu código:

(function(){}())

¡La inserción automática de punto y coma no se activará! ¿El resultado? se obj.prop función obj.prop , con nuestro IIFE pasado como argumento. Esto lo hará más obvio:

obj.prop = function() { // Do something big and awful }(function(){}())

¿Ves cómo esos () ahora invocan la función?

Similar:

obj.criticalValue = 42

entonces

+function(){}()

De repente, criticalValue está en mal estado. ¿Por qué? Porque:

obj.criticalValue = 42+function(){}()

Doh!

Tener múltiples ; en una fila es inofensivo, por lo que si comienza con uno, es menos probable que tenga problemas.

He empezado a leer this libro. El Capítulo 2 dice que hay diferentes formas de escribir un IIFE:

!function (){}() ~function (){}() +function (){}() -function (){}() new function (){} 1,function (){}() 1&&function (){}() var i=function (){}()

El autor dice:

Cada manifestación tiene sus propias cualidades y ventajas únicas: algunas con menos bytes, otras más seguras para la concatenación, cada una válida y cada una ejecutable.

Soy un novato en JS. Sé lo que es un IIFE, pero ¿qué hacen exactamente estas formas IIFE?


Es una optimización para concatenar múltiples archivos en uno. La idea es que si la última línea del archivo anterior no termina con una nueva línea, entonces la primera línea de este archivo comienza en el medio de una línea.

Agregando cosas como ; antes de que la función permita que siga funcionando correctamente.