stringtranslate.com

Expresión de función invocada inmediatamente

Una expresión de función invocada inmediatamente (o IIFE , pronunciada "iffy", IPA /ˈɪf.i/) es un modismo del lenguaje de programación que produce un alcance léxico utilizando el alcance de función . Fue popular en JavaScript [1] como un método para respaldar la programación modular antes de la introducción de soluciones más estandarizadas como CommonJS y los módulos ES . [2]

Las expresiones de función invocadas inmediatamente se pueden usar para evitar la elevación de variables desde dentro de bloques, proteger contra la contaminación del medio ambiente global y, simultáneamente, permitir el acceso público a los métodos mientras se conserva la privacidad de las variables definidas dentro de la función.

Uso

Las expresiones de función invocadas inmediatamente pueden escribirse de varias maneras diferentes. [3] Una convención común es encerrar la expresión de función (y opcionalmente su operador de invocación) con el operador de agrupación, [4] entre paréntesis, para indicarle al analizador explícitamente que espere una expresión. De lo contrario, en la mayoría de las situaciones, cuando el analizador encuentra la functionpalabra clave, la trata como una declaración de función (sentencia), y no como una expresión de función. [5] [6]

( function () { /* ... */ })(); ( function () { /* ... */ }()); (() => { /* ... */ })(); // Con funciones de flecha ES6 (aunque los paréntesis solo se permiten en el exterior)             

Hay otras formas de hacer cumplir una expresión de función: [ cita requerida ]

! función () { /* ... */ }(); ~ función () { /* ... */ }(); - función () { /* ... */ }(); + función () { /* ... */ }(); void función () { /* ... */ }(); eliminar función () { /* ... */ }(); tipo de función () { /* ... */ }(); esperar función () { /* ... */ }();                                    

En contextos donde se espera una expresión, no es necesario encerrarla entre paréntesis:

sea ​​f = función () { /* ... */ }(); verdadero && función () { /* ... */ }(); 0 , función () { /* ... */ }();                  

El paso de variables al ámbito se realiza de la siguiente manera:

( función ( a , b ) { /* ... */ })( "hola" , "mundo" );     

Un paréntesis inicial es un caso en el que la inserción automática de punto y coma (ASI) en JavaScript puede causar problemas; la expresión se interpreta como una llamada al último término de la línea anterior. En algunos estilos que omiten los puntos y coma opcionales, el punto y coma se coloca delante del paréntesis y se conoce como punto y coma defensivo . [7] [8] Por ejemplo:

a = b + c ;( función () { // código })();       

...para evitar ser analizado como c().

Ejemplos

La clave para entender patrones de diseño como IIFE es darse cuenta de que antes de ES6, JavaScript solo presentaba un alcance de función (por lo que carecía de alcance de bloque ), pasando valores por referencia dentro de cierres . [9] Esto ya no es así, ya que la versión ES6 de JavaScript implementa el alcance de bloque usando las nuevas palabras clave lety [10]const

Contexto de evaluación

La falta de alcance de bloque significa que las variables definidas dentro de (por ejemplo) un bucle for tendrán su definición "elevada" a la parte superior de la función que las contiene. Evaluar una función que depende de variables modificadas por la función externa (incluso por iteración) puede ser difícil. Podemos ver esto sin un bucle si actualizamos un valor entre la definición y la invocación de la función. [11]

sea ​​v , obtenerValor ; v = 1 ; obtenerValor = función () { devolver v ; }; v = 2 ;             obtenerValor (); // 2 

Si bien el resultado puede parecer obvio cuando se actualiza vmanualmente, puede producir resultados no deseados cuando getValue()se define dentro de un bucle.

A partir de ahora la función pasa vcomo argumento y se invoca inmediatamente, preservando el contexto de ejecución de la función interna. [12]

sea ​​v , obtenerValor ; v = 1 ; obtenerValor = ( función ( x ) { devolver función () { devolver x ; }; })( v ); v = 2 ;                 obtenerValor (); // 1 

Esto es equivalente al siguiente código:

sea ​​v , obtenerValor ; v = 1 ; función f ( x ) { devolver función () { devolver x ; }; }; obtenerValor = f ( v ); v = 2 ;                 obtenerValor (); // 1 

Establecimiento de variables privadas y accesores

Las IIFE también son útiles para establecer métodos privados para funciones accesibles y al mismo tiempo exponer algunas propiedades para su uso posterior. [13] El siguiente ejemplo proviene de la publicación de Alman sobre IIFE. [1]

// "counter" es una función que devuelve un objeto con propiedades, que en este caso son funciones. let counter = ( function () { let i = 0 ;          retorna { obtener : función () { retorna i ; }, establecer : función ( val ) { i = val ; }, incrementar : función () { retorna ++ i ; } }; })();                        // Estas llamadas acceden a las propiedades de la función devueltas por "counter". counter . get (); // 0 counter . set ( 3 ); counter . increment (); // 4 counter . increment (); // 5   

Si intentamos acceder counter.idesde el entorno global, no estará definido, ya que está incluido dentro de la función invocada y no es una propiedad de counter. Del mismo modo, si intentamos acceder a i, se producirá un error, ya que no lo hemos declarado ien el entorno global.

Terminología

Originalmente conocida como una "función anónima autoejecutable", [14] Ben Alman introdujo más tarde el término actual IIFE como un nombre semánticamente más preciso para el modismo, poco después de que surgiera su discusión en comp.lang.javascript. [1] [15] [16]

En particular, las funciones invocadas inmediatamente no necesitan ser anónimas de forma inherente, y el modo estricto de ECMAScript 5 prohíbe , [17] lo que hace que el término original sea un nombre inapropiado . arguments.callee

Véase también

Referencias

  1. ^ abc Alman, Ben (15 de noviembre de 2010). «Expresiones de función invocadas inmediatamente». Archivado desde el original el 1 de diciembre de 2017. Consultado el 18 de enero de 2019 .
  2. ^ McGinnis, Tyler (15 de enero de 2019). "Módulos de JavaScript: desde IIFE hasta CommonJS y módulos ES6". ui.dev . Consultado el 18 de agosto de 2021 .
  3. ^ Lindley, Cody (2013). JavaScript Enlightenment . O'Reilly. pág. 61. ISBN 978-1-4493-4288-3.
  4. ^ "Operador de agrupación". Mozilla Developer Network. 2 de octubre de 2023.
  5. ^ Zakas, Nicholas (2012). JavaScript mantenible . O'Reilly. pág. 44. ISBN 978-1-4493-2768-2.
  6. ^ Axel Rauschmayer. "ExplorandoJS".
  7. ^ "Inserción de punto y coma en JavaScript: todo lo que necesita saber". 28 de mayo de 2010. Archivado desde el original el 2 de octubre de 2017.
  8. ^ Marohnić, Mislav (7 de mayo de 2010). «Los puntos y comas en JavaScript son opcionales». Archivado desde el original el 8 de agosto de 2017.
  9. ^ Haverbeke, Marijn (2011). JavaScript elocuente . Sin prensa de almidón. págs. 29 y 30. ISBN 978-1-59327-282-1.
  10. ^ ECMAScript 6: Nuevas características: descripción general y comparación, variables con alcance de bloque
  11. ^ Alman, Ben. "simple-iife-example.js". Github . Consultado el 5 de febrero de 2013 .
  12. ^ Otero, Cesar; Larsen, Rob (2012). JQuery profesional . John Wiley & Sons. pág. 31. ISBN 978-1-118-22211-9.
  13. ^ Rettig, Pascal (2012). Desarrollo profesional de juegos móviles en HTML5 . John Wiley & Sons. pág. 145. ISBN 978-1-118-30133-3.
  14. ^ Resig, John (2006). Técnicas profesionales de JavaScript . Presione. pag. 29.ISBN 978-1-4302-0283-7.
  15. ^ Osmani, Addy (2012). Aprendizaje de patrones de diseño de JavaScript . O'Reilly. pág. 206. ISBN 978-1-4493-3487-1.
  16. ^ Baagoe, Johannes. «Cerrar paréntesis en la definición de una función seguida de su llamada» . Consultado el 19 de abril de 2010 .
  17. ^ "Modo estricto". Referencia de JavaScript de Mozilla . Red de desarrolladores de Mozilla . Consultado el 4 de febrero de 2013 .

Enlaces externos