stringtranslate.com

Expresión de función inmediatamente invocada

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

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

Uso

Las expresiones de funciones inmediatamente invocadas se pueden escribir de varias maneras diferentes. [3] Una convención común es encerrar la expresión de la función (y opcionalmente su operador de invocación) con el operador de agrupación, [4] entre paréntesis, para indicarle explícitamente al analizador 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 (declaración) y no como una expresión de función. [5] [6]

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

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

! función () { /* ... */ }(); ~ función () { /* ... */ }(); - función () { /* ... */ }(); + función () { /* ... */ }(); función vacía () { /* ... */ }(); eliminar función () { /* ... */ }(); tipo de función () { /* ... */ }(); función de espera () { /* ... */ }();                                    

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

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

Pasar variables al alcance 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; en cambio, la expresión se interpreta como una llamada al último término de la línea anterior. En algunos estilos que omiten el punto y coma opcional, 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 comprender patrones de diseño como IIFE es darse cuenta de que antes de ES6, JavaScript solo presentaba un alcance de función (por lo tanto, carecía de alcance de bloque ), pasando valores por referencia dentro de cierres . [9] Este ya no es el caso, ya que la versión ES6 de JavaScript implementa el alcance del bloque utilizando las palabras clave new lety const. [10]

Contexto de evaluación

La falta de alcance del bloque significa que las variables definidas dentro (por ejemplo) de un bucle for tendrán su definición "elevada" a la parte superior de la función adjunta. Evaluar una función que depende de variables modificadas por la función externa (incluso por iteración) puede resultar 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]

let v , getValue ; v = 1 ; getValue = function () { return 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.

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

let v , getValue ; v = 1 ; getValue = ( función ( x ) { función de retorno () { retorno x ; }; })( v ); v = 2 ;                 obtenerValor (); // 1 

Esto es equivalente al siguiente código:

let v , getValue ; v = 1 ; función f ( x ) { función de retorno () { retorno x ; }; }; obtenerValor = f ( v ); v = 2 ;                 obtenerValor (); // 1 

Establecer variables privadas y accesores.

Los 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]

// "contador" es una función que devuelve un objeto con propiedades, que en este caso son funciones. let contador = ( function () { let i = 0 ;          return { obtener : función () { return i ; }, establecer : función ( val ) { i = val ; }, incremento : función () { retorno ++ i ; } }; })();                        // Estas llamadas acceden a las propiedades de la función devueltas por "contador". encimera . conseguir (); // 0 contador . conjunto ( 3 ); encimera . incremento (); // 4 contadores . incremento (); // 5   

Si intentamos acceder counter.idesde el entorno global, será indefinido, ya que está incluido dentro de la función invocada y no es una propiedad de counter. Asimismo, si intentamos acceder i, resultará en 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 inherentemente anónimas, y el modo estricto de ECMAScript  5 lo prohíbe arguments.callee, [17] convirtiendo el término original en un nombre inapropiado .

Ver también

Referencias

  1. ^ abc Alman, Ben (15 de noviembre de 2010). "Expresiones de funciones 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: de IIFE a CommonJS y módulos ES6". ui.dev . Consultado el 18 de agosto de 2021 .
  3. ^ Lindley, Cody (2013). Iluminación de JavaScript . O'Reilly. pag. 61.ISBN 978-1-4493-4288-3.
  4. ^ "Operador de agrupación". Red de desarrolladores de Mozilla.
  5. ^ Zakas, Nicolás (2012). JavaScript mantenible . O'Reilly. pag. 44.ISBN 978-1-4493-2768-2.
  6. ^ Axel Rauschmayer. "ExplorandoJS".
  7. ^ "Inserción de punto y coma de 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). "El punto y coma en JavaScript es opcional". 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 funciones: descripción general y comparación, variables con alcance de bloque
  11. ^ Alma, Ben. "simple-iife-ejemplo.js". Github . Consultado el 5 de febrero de 2013 .
  12. ^ Otero, César; Larsen, Rob (2012). jQuery profesional . John Wiley e hijos. pag. 31.ISBN 978-1-118-22211-9.
  13. ^ Rettig, Pascal (2012). Desarrollo profesional de juegos móviles HTML5 . John Wiley e hijos. pag. 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. pag. 206.ISBN 978-1-4493-3487-1.
  16. ^ Baagoe, Johannes. "Paréntesis de cierre en la definición de la función seguido 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