attribute - ¿Qué es la construcción(function(){})() en JavaScript?
title css (23)
Una expresión de función invocada inmediatamente (IIFE) es una función que se ejecuta tan pronto como se crea. No tiene conexión con ningún evento o ejecución asíncrona. Puede definir un IIFE como se muestra a continuación:
(function() {
// all your code here
// ...
})();
La primera función de paréntesis () {...} convierte el código dentro de paréntesis en una expresión. La segunda pareja de paréntesis llama a la función resultante de la expresión.
Un IIFE
también se puede describir como una función anónima que se invoca a sí misma. Su uso más común es limitar el alcance de una variable hecha a través de var o para encapsular el contexto para evitar colisiones de nombres.
Solía saber qué significaba esto, pero ahora estoy luchando ...
¿Esto es básicamente decir document.onload
?
(function () {
})();
Creo que los 2 conjuntos de paréntesis lo hacen un poco confuso, pero vi otro uso en el ejemplo de Google, ellos usaron algo similar, espero que esto te ayude a entender mejor:
var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);
por lo tanto, si windows.app
no está definido, entonces window.app = {}
se ejecuta inmediatamente, por lo que window.app
se asigna con {}
durante la evaluación de la condición, por lo que el resultado es app
y window.app
ahora se convierten en {}
, por lo que La salida de la consola es:
Object {}
Object {}
Declara una función anónima, luego la llama:
(function (local_arg) {
// anonymous function
console.log(local_arg);
})(arg);
El siguiente código:
(function () {
})();
Se llama una expresión de función invocada inmediatamente (IIFE).
Se llama expresión de función porque el operador ( yourcode )
en Javascript lo fuerza en una expresión. La diferencia entre una expresión de función y una declaración de función es la siguiente:
// declaration:
function declaredFunction () {}
// expressions:
// storing function into variable
const expressedFunction = function () {}
// Using () operator, which transforms the function into an expression
(function () {})
Una expresión es simplemente un montón de código que puede evaluarse a un solo valor . En el caso de las expresiones en el ejemplo anterior, este valor era un objeto de función única .
Después de que tengamos una expresión que evalúe un objeto de función, podemos invocar inmediatamente el objeto de función con el operador ()
. Por ejemplo:
(function() {
const foo = 10; // all variables inside here are scoped to the function block
console.log(foo);
})();
console.log(foo); // referenceError foo is scoped to the IIFE
¿Por qué es esto útil?
Cuando tratamos con una base de código grande y / o cuando importamos varias bibliotecas, aumenta la posibilidad de conflictos de nombres. Cuando escribimos ciertas partes de nuestro código que están relacionadas (y, por lo tanto, están utilizando las mismas variables) dentro de un IIFE, todas las variables y nombres de funciones tienen el alcance de los corchetes de funciones del IIFE . Esto reduce las posibilidades de conflictos de nombres y le permite darles un nombre más descuidado (por ejemplo, no tiene que prefijarlos).
Empieza aqui:
var b = ''bee'';
console.log(b); // global
Póngalo en una función y ya no es global , su objetivo principal.
function a() {
var b = ''bee'';
console.log(b);
}
a();
console.log(b); // ReferenceError: b is not defined -- *as desired*
Llame a la función inmediatamente - oops:
function a() {
var b = ''bee'';
console.log(b);
}(); // SyntaxError: Expected () to start arrow function, but got '';'' instead of ''=>''
Utilice los paréntesis para evitar un error de sintaxis:
(function a() {
var b = ''bee'';
console.log(b);
})(); // OK now
Puedes omitir el nombre de la función:
(function () { // no name required
var b = ''bee'';
console.log(b);
})();
No necesita ser más complicado que eso.
Es solo una función anónima que se ejecuta justo después de ser creada.
Es como si lo asignaras a una variable y la usaras justo después, solo que sin la variable:
var f = function () {
};
f();
En jQuery hay una construcción similar en la que podrías estar pensando:
$(function(){
});
Esa es la forma corta de atar el evento ready
:
$(document).ready(function(){
});
Es una benalman.com/news/2010/11/… , o IIFE para abreviar. Se ejecuta inmediatamente después de su creación.
No tiene nada que ver con ningún controlador de eventos para ningún evento (como document.onload
).
Considere la parte dentro del primer par de paréntesis: ( function(){} )();
.... es una expresión de función regular. Luego mira el último par (function(){}) () ;
, esto normalmente se agrega a una expresión para llamar a una función; En este caso, nuestra expresión previa.
Este patrón se usa a menudo cuando se intenta evitar contaminar el espacio de nombres global, porque todas las variables utilizadas dentro del IIFE (como en cualquier otra función normal ) no son visibles fuera de su alcance.
Esta es la razón por la que, tal vez, confundiste esta construcción con un controlador de eventos para window.onload
, porque a menudo se usa así:
(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)
Corrección sugerida por Guffa :
La función se ejecuta justo después de crearla, no después de analizarla. El bloque de script completo se analiza antes de que se ejecute cualquier código en él. Además, el código de análisis no significa automáticamente que se ejecuta, si, por ejemplo, el IIFE está dentro de una función, no se ejecutará hasta que se llame a la función.
Esa construcción se llama Expresión de función invocada inmediatamente (IIFE), lo que significa que se ejecuta de inmediato. Piense en ello como una función que se llama automáticamente cuando el intérprete llega a esa función.
Caso de uso más común:
Uno de sus casos de uso más comunes es limitar el alcance de una variable creada a través de var
. Las variables creadas mediante var
tienen un alcance limitado a una función, por lo que esta construcción (que es una envoltura de función alrededor de cierto código) se asegurará de que el alcance de su variable no se escape de esa función.
En el siguiente ejemplo, el recuento no estará disponible fuera de la función invocada de inmediato, es decir, el alcance del count
no se perderá de la función. Debería obtener un Reference Error
, en caso de que intente acceder a él fuera de la función inmediatamente invocada.
(function () {
var count = 10;
})();
console.log(count); // Reference Error: count is not defined
Alternativa ES6 (Recomendado)
En ES6, ahora podemos tener variables creadas a través de let
y const
. Ambos son de ámbito de bloque (a diferencia de var
que es un ámbito de función).
Por lo tanto, en lugar de usar esa construcción compleja de IIFE para el caso de uso que mencioné anteriormente, ahora puede escribir un código mucho más simple para asegurarse de que el alcance de una variable no se escape del bloque deseado.
{
let count = 10;
};
console.log(count); // Reference Error: count is not defined
En este ejemplo, usamos let
para definir una variable de count
que hace que el count
limite al bloque de código, que creamos con las llaves {...}
.
Yo lo llamo una Curly Jail
.
Esa es una función anónima de auto-invocación .
Echa un vistazo a la explicación de W3Schools de una función de auto-invocación .
Las expresiones de función se pueden hacer "auto-invocación".
Una expresión de invocación automática se invoca (inicia) automáticamente, sin ser invocada.
Las expresiones de función se ejecutarán automáticamente si la expresión es seguida por ().
No se puede invocar una declaración de función.
Eso es decir ejecutar inmediatamente.
así que si lo hago:
var val = (function(){
var a = 0; // in the scope of this function
return function(x){
a += x;
return a;
};
})();
alert(val(10)); //10
alert(val(11)); //21
Fiddle: http://jsfiddle.net/maniator/LqvpQ/
Segundo ejemplo:
var val = (function(){
return 13 + 5;
})();
alert(val); //18
Esta es la función anónima de auto-invocación. Se ejecuta mientras está definido. Lo que significa que esta función está definida y se invoca inmediatamente después de la definición.
Y la explicación de la sintaxis es: La función dentro del primer paréntesis ()
es la función que no tiene nombre y junto al siguiente ();
paréntesis usted puede entender que se llama en el momento en que se define. Y puede pasar cualquier argumento en este segundo ()
paréntesis que se capturará en la función que está en el primer paréntesis. Vea este ejemplo:
(function(obj){
// Do something with this obj
})(object);
Aquí se podrá acceder al ''objeto'' que está pasando dentro de la función mediante ''obj'', ya que lo está capturando en la firma de la función.
Esta es una función anónima que es auto invocante . Comúnmente conocido como una expresión de función invocada de inmediato (IIFE).
Esta es una expresión de función invocada de inmediato en Javascript:
Para entender IIFE en JS, vamos a desglosarlo:
- Expresión : Algo que devuelve un valor.
Ejemplo: Prueba a seguir en la consola de chrome. Estas son expresiones en JS.
a = 10 output = 10 (1+3) output = 4
- Expresión de la función :
Ejemplo:
// Function Expression var greet = function(name){ return ''Namaste'' + '' '' + name; } greet(''Santosh'');
Cómo funciona la expresión de función:
- Cuando el motor JS se ejecuta por primera vez (Contexto de ejecución - Crear fase), esta función (en el lado derecho de = arriba) no se ejecuta ni se almacena en la memoria. El motor JS asigna un valor "no definido" a la variable "saludo".
- Durante la ejecución (Contexto de ejecución - Fase de ejecución), el objeto de la función se crea sobre la marcha ( aún no se ha ejecutado ), se asigna a la variable ''greet'' y se puede invocar usando ''greet ('' somename '')''.
3. Expresión de Funtion inmediatamente invocada:
Ejemplo:
// IIFE
var greeting = function(name) {
return ''Namaste'' + '' '' + name;
}(''Santosh'')
console.log(greeting) // Namaste Santosh.
Cómo funciona IIFE :
- Observe el ''()'' inmediatamente después de la declaración de la función. Cada objeto de función tiene una propiedad ''CÓDIGO'' adjunta que es invocable. Y podemos llamarlo (o invocarlo) usando llaves ''()''.
- Entonces, aquí, durante la ejecución (Contexto de ejecución - Ejecutar fase), el objeto de función se crea y se ejecuta al mismo tiempo . Entonces, la variable de saludo, en lugar de tener el objeto de función, tiene su valor de retorno (una cadena)
Caso de uso típico de IIFE en JS:
El siguiente patrón de IIFE es muy comúnmente usado.
// IIFE
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = ''Namaste'';
console.log(greeting + '' '' + name);
})(''Santosh'');
- Estamos haciendo dos cosas aquí. a) Envolviendo nuestra expresión de función dentro de llaves (). Esto le dice al analizador de sintaxis que lo que se coloque dentro de () es una expresión (expresión de función en este caso) y es un código válido.
b) Estamos invocando esta función al mismo tiempo utilizando el () al final de la misma.
Así que esta función se crea y ejecuta al mismo tiempo (IIFE).
Importante caso de uso para IIFE:
IIFE mantiene nuestro código a salvo.
- IIFE, al ser una función, tiene su propio contexto de ejecución, lo que significa que todas las variables creadas en su interior son locales para esta función y no se comparten con el contexto de ejecución global.
Supongamos que he usado otro archivo JS (test1.js) en mi aplicación junto con iife.js (ver más abajo).
// test1.js
var greeting = ''Hello'';
// iife.js
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = ''Namaste'';
console.log(greeting + '' '' + name);
})(''Santosh'');
console.log(greeting) // No collision happens here. It prints ''Hello''.
Así que IIFE nos ayuda a escribir código seguro donde no estamos chocando con los objetos globales involuntariamente.
Función anónima autoejecutable. Se ejecuta tan pronto como se crea.
Un ejemplo corto y ficticio donde esto es útil es:
function prepareList(el){
var list = (function(){
var l = [];
for(var i = 0; i < 9; i++){
l.push(i);
}
return l;
})();
return function (el){
for(var i = 0, l = list.length; i < l; i++){
if(list[i] == el) return list[i];
}
return null;
};
}
var search = prepareList();
search(2);
search(3);
Entonces, en lugar de crear una lista cada vez, la creas solo una vez (menos sobrecarga).
IIFE (expresión de función invocada de inmediato) es una función que se ejecuta tan pronto como el script se carga y desaparece.
Considere la siguiente función escrita en un archivo llamado iife.js
(function(){
console.log("Hello !");
})();
Este código de arriba se ejecutará tan pronto como cargues iife.js e imprimirá '' Hello ! ''en la consola de herramientas de desarrollo''.
Para una explicación detallada, vea benalman.com/news/2010/11/…
La razón por la que se usan las funciones anónimas que se evocan a sí mismas es que nunca deben ser invocadas por otro código, ya que "configuran" el código que se debe llamar (junto con el alcance de funciones y variables).
En otras palabras, son como programas que "hacen clases", al principio del programa. Después de que se crean instancias (automáticamente), las únicas funciones que están disponibles son las que devuelve la función anónima. Sin embargo, todas las demás '' Las funciones "ocultas" aún están allí, junto con cualquier estado (variables establecidas durante la creación del ámbito).
Muy genial.
Las funciones de ejecución automática se utilizan normalmente para encapsular el contexto y evitar las confusiones de nombres. Cualquier variable que defina dentro de (function () {..}) () no es global.
El código
var same_name = 1;
var myVar = (function() {
var same_name = 2;
console.log(same_name);
})();
console.log(same_name);
produce esta salida:
2
1
Al usar esta sintaxis, evita chocar con variables globales declaradas en otro lugar en su código JavaScript.
No, esta construcción solo crea un ámbito para nombrar. Si lo rompes en partes puedes ver que tienes un externo
(...)();
Esa es una invocación de función. Dentro del paréntesis tienes:
function() {}
Esa es una función anónima. Todo lo que se declara con var dentro del constructo será visible solo dentro del mismo constructo y no contaminará el espacio de nombres global.
Normalmente el código javascrypt tiene alcance global en la aplicación. Cuando declaramos una variable global en ella, existe la posibilidad de usar la misma variable duplicada en alguna otra área del desarrollo para algún otro propósito. Debido a esta duplicación puede ocurrir algún error. Por lo tanto, podemos evitar estas variables globales utilizando la expresión de la función de invocación inmediata, esta expresión es una expresión autoejecutable. Cuando hacemos que nuestro código dentro de esta expresión de IIFE , la variable global será como el alcance local y la variable local.
De dos maneras podemos crear IIFE
(function () {
"use strict";
var app = angular.module("myModule", []);
}());
O
(function () {
"use strict";
var app = angular.module("myModule", []);
})();
En el fragmento de código anterior, " var app " es una variable local ahora.
Por lo general, no invocamos una función inmediatamente después de escribirla en el programa. En términos extremadamente simples, cuando llama a una función inmediatamente después de su creación, se llama IIFE, un nombre elegante.
Un caso de uso más es la memorización donde un objeto de caché no es global:
var calculate = (function() {
var cache = {};
return function(a) {
if (cache[a]) {
return cache[a];
} else {
// Calculate heavy operation
cache[a] = heavyOperation(a);
return cache[a];
}
}
})();
Una expresión de función inmediatamente invocada (IIFE) llama inmediatamente a una función. Esto simplemente significa que la función se ejecuta inmediatamente después de completar la definición.
Tres palabras más comunes:
// Crockford''s preference - parens on the inside
(function() {
console.log(''Welcome to the Internet. Please follow me.'');
}());
//The OPs example, parentheses on the outside
(function() {
console.log(''Welcome to the Internet. Please follow me.'');
})();
//Using the exclamation mark operator
//https://.com/a/5654929/1175496
!function() {
console.log(''Welcome to the Internet. Please follow me.'');
}();
Si no hay requisitos especiales para su valor de retorno, entonces podemos escribir:
!function(){}(); // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}(); // => NaN
Alternativamente, puede ser:
~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();
Incluso puedes escribir:
new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required
(function () {
})();
Esto se llama IIFE (expresión de función invocada de inmediato). Uno de los famosos patrones de diseño javascript, y es el corazón y el alma de los patrones modernos de módulos. Como su nombre indica, se ejecuta inmediatamente después de su creación. Este patrón crea un ámbito de ejecución aislado o privado.
JavaScript antes de ECMAScript 6 utilizando el alcance léxico, IIFE se utiliza para simular el alcance del bloque. (Con ECMAScript 6, el alcance del bloque es posible con la introducción de la palabra clave let y const.) Referencia para el problema con el alcance léxico
Simular el alcance del bloque con IIFE
El beneficio de rendimiento de usar IIFE es la capacidad de pasar objetos globales de uso común como ventanas, documentos, etc. Como argumento al reducir la búsqueda de alcance (recuerde que Javascript busca propiedades en un alcance local y se encadena hasta el alcance global). Para acceder a los objetos globales en el ámbito local, reduzca el tiempo de búsqueda como se muestra a continuación.
(function (globalObj) {
//Access the globalObj
})(window);