Solía saber lo que esto significaba, pero ahora estoy luchando ...
¿Esto es básicamente decir document.onload
?
(function () {
})();
Solía saber lo que esto significaba, pero ahora estoy luchando ...
¿Esto es básicamente decir document.onload
?
(function () {
})();
Respuestas:
Es una expresión de función invocada inmediatamente , 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: ... es una expresión de función regular. Luego mire el último par , esto normalmente se agrega a una expresión para llamar a una función; En este caso, nuestra expresión previa.(function(){})();
(function(){})();
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 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 que se crea, no después de que se analiza. El bloque de secuencia de comandos completo se analiza antes de que se ejecute ningún código. Además, el código de análisis no significa automáticamente que se ejecute, si, por ejemplo, el IIFE está dentro de una función, no se ejecutará hasta que se llame a la función.
Actualización Dado que este es un tema bastante popular, vale la pena mencionar que los IIFE también se pueden escribir con la función de flecha de ES6 (como Gajus ha señalado en un comentario ):
((foo) => {
// do something with foo here foo
})('foo value')
function(){ var foo = '5'; }
Es solo una función anónima que se ejecuta inmediatamente después de su creación.
Es como si lo hubieras asignado a una variable y lo hubieras usado inmediatamente después, solo 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 abreviada de vincular el ready
evento:
$(document).ready(function(){
});
Pero las dos construcciones anteriores no son IIFE s.
Una expresión de función invocada inmediatamente (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://stackoverflow.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
31.new
'es una sintaxis no válida
;(function(){}());
1 - 1
y puedes hacerlo con la misma facilidad true - function(){}
. Es solo una cosa (un operador de resta infijo) pero con operandos diferentes, incluso sin sentido.
Declara una función anónima, luego la llama:
(function (local_arg) {
// anonymous function
console.log(local_arg);
})(arg);
Es decir ejecutar inmediatamente.
entonces 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
Violín: http://jsfiddle.net/maniator/LqvpQ/
var val = (function(){
return 13 + 5;
})();
alert(val); //18
Esa construcción se llama una expresión de función invocada inmediatamente (IIFE) 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 hecha a través de var
. Las variables creadas a través de var
tienen un alcance limitado a una función, por lo que esta construcción (que es un envoltorio de función alrededor de cierto código) se asegurará de que su alcance variable no se filtre fuera de esa función.
En el siguiente ejemplo, count
no estará disponible fuera de la función invocada inmediatamente, es decir, el alcance de count
no se escapará de la función. Debería obtener un ReferenceError
, si intenta acceder a él fuera de la función invocada inmediatamente de todos modos.
(function () {
var count = 10;
})();
console.log(count); // Reference Error: count is not defined
Alternativa ES6 (recomendada)
En ES6, ahora podemos tener variables creadas mediante let
y const
. Ambos tienen ámbito de bloque (a diferencia de lo var
que es á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 filtre fuera del bloque deseado.
{
let count = 10;
}
console.log(count); // ReferenceError: count is not defined
En este ejemplo, solíamos let
definir una count
variable que se count
limita al bloque de código, creamos con los corchetes{...}
.
Yo lo llamo una "cárcel rizada".
(function () {
})();
Esto se llama IIFE (Expresión de función invocada inmediatamente). Uno de los famosos patrones de diseño de JavaScript, es el corazón y el alma del patrón del Módulo moderno. 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 anterior a ECMAScript 6 usaba el alcance léxico, por lo tanto, IIFE se usaba para simular el alcance del bloque. (Con el alcance del bloque ECMAScript 6 es posible con la introducción de las palabras clave let
y const
.)
Referencia para el problema con el alcance léxico
Simule el alcance del bloque con IIFE
La mejora en el rendimiento de la utilización de IIFE es la capacidad de pasar objetos globales utilizados comúnmente como window
, document
, etc., como un argumento mediante la reducción de las operaciones de búsqueda alcance. (Recuerde que JavaScript busca propiedades en el ámbito local y en la cadena hasta el alcance global). Por lo tanto, acceder a objetos globales en el ámbito local reduce el tiempo de búsqueda como se muestra a continuación.
(function (globalObj) {
//Access the globalObj
})(window);
No, esta construcción solo crea un ámbito para nombrar. Si lo rompe en partes, puede ver que tiene un
(...)();
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 declare con var dentro de la construcción será visible solo dentro de la misma construcción y no contaminará el espacio de nombres global.
Esta es una expresión de función invocada inmediatamente en Javascript:
Para comprender IIFE en JS, analicemos:
a = 10 output = 10 (1+3) output = 4
// 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 "indefinido" a la variable "saludar".
- Durante la ejecución (contexto de ejecución - fase de ejecución), el objeto de función se crea sobre la marcha ( aún no se ha ejecutado ), se asigna a la variable 'saludar' y se puede invocar usando 'saludar (' nombre de pila ')'.
3. Expresión de función invocada inmediatamente:
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 - Fase de ejecución), se crea el objeto de función y se ejecuta al mismo tiempo
- Entonces, ahora, 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 IIFE se usa con bastante frecuencia.
// IIFE
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = 'Namaste';
console.log(greeting + ' ' + name);
})('Santosh');
Entonces, esta función se crea y ejecuta al mismo tiempo (IIFE).
Caso de uso importante para IIFE:
IIFE mantiene nuestro código seguro.
- 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 tengo otro archivo JS (test1.js) usado 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'.
Por lo tanto, IIFE nos ayuda a escribir código seguro donde no estamos colisionando involuntariamente con los objetos globales.
Esa es una función anónima que se invoca a sí misma .
Echa un vistazo a la explicación de W3Schools de una función de auto invocación .
Las expresiones de función pueden hacerse "auto-invocantes".
Una expresión autoinvocatoria se invoca (inicia) automáticamente, sin ser llamada.
Las expresiones de función se ejecutarán automáticamente si la expresión es seguida por ().
No puede auto invocar una declaración de función.
(function named(){console.log("Hello");}());
<- función nombrada de ejecución
Esta es la función anónima autoinvocatoria. 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 por el siguiente ();
paréntesis puedes entender que se llama en el momento en que se define. Y puede pasar cualquier argumento en este segundo ()
paréntesis que se tomará en la función que está en el primer paréntesis. Ver este ejemplo:
(function(obj){
// Do something with this obj
})(object);
Aquí el 'objeto' que está pasando será accesible dentro de la función mediante 'obj', ya que lo está agarrando en la firma de la función.
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 de inmediato - oops:
function a() {
var b = 'bee';
console.log(b);
}(); // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'
Use los paréntesis para evitar un error de sintaxis:
(function a() {
var b = 'bee';
console.log(b);
})(); // OK now
Puede dejar el nombre de la función:
(function () { // no name required
var b = 'bee';
console.log(b);
})();
No necesita ser más complicado que eso.
Uncaught SyntaxError: Unexpected token )
más que cualquier mención de la función de flecha. ¿Podría compartir un violín con el error de función de flecha?
Función anónima autoejecutable. Se ejecuta tan pronto como se crea.
Un ejemplo breve 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 crea solo una vez (menos gastos generales).
Las funciones de ejecución automática se utilizan generalmente para encapsular el contexto y evitar colusiones 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, evitas colisionar con variables globales declaradas en otra parte de tu código JavaScript.
var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name);
Tendría el mismo resultado.
Se llama IIFE - Expresión de función invocada inmediatamente. Aquí hay un ejemplo para mostrar su sintaxis y uso. Se utiliza para determinar el uso de variables solo hasta la función y no más allá.
(function () {
function Question(q,a,c) {
this.q = q;
this.a = a;
this.c = c;
}
Question.prototype.displayQuestion = function() {
console.log(this.q);
for (var i = 0; i < this.a.length; i++) {
console.log(i+": "+this.a[i]);
}
}
Question.prototype.checkAnswer = function(ans) {
if (ans===this.c) {
console.log("correct");
} else {
console.log("incorrect");
}
}
var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);
var questions = [q1, q2, q3];
var n = Math.floor(Math.random() * questions.length)
var answer = parseInt(prompt(questions[n].displayQuestion()));
questions[n].checkAnswer(answer);
})();
IIFE (expresión de función invocada inmediatamente) es una función que se ejecuta tan pronto como se carga el script y desaparece.
Considere la siguiente función escrita en un archivo llamado iife.js
(function(){
console.log("Hello Stackoverflow!");
})();
Este código anterior se ejecutará tan pronto como cargue iife.js e imprimirá ' Hello Stackoverflow! 'en la consola de herramientas de desarrollador'.
Para obtener una explicación detallada, consulte Expresión de función invocada inmediatamente (IIFE)
Otro caso de uso 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 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 asincrónica. Puede definir un IIFE como se muestra a continuación:
(function() {
// all your code here
// ...
})();
El primer par de paréntesis función () {...} convierte el código dentro de los paréntesis en una expresión. El segundo par de paréntesis llama a la función resultante de la expresión.
An IIFE
también se puede describir como una función anónima autoinvocatoria. Su uso más común es limitar el alcance de una variable hecha a través de var o encapsular el contexto para evitar colisiones de nombres.
La razón por la que se utilizan funciones anónimas autoevocadoras es que nunca deben ser llamadas por otro código, ya que "configuran" el código que se quiere llamar (junto con dar alcance a las funciones y variables).
En otras palabras, son como programas que "hacen clases", al comienzo del programa. Después de que se crean instancias (automáticamente), las únicas funciones que están disponibles son las devueltas por la función anónima. Sin embargo, todas las demás " las funciones ocultas todavía están allí, junto con cualquier estado (variables establecidas durante la creación del alcance).
Muy genial.
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 ( yourcode )
operador en Javascript la fuerza a 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 se puede evaluar con 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 tener una expresión que se evalúa como 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
Cuando tratamos con una base de código grande y / o cuando importamos varias bibliotecas, aumenta la posibilidad de nombrar conflictos. Cuando estamos escribiendo ciertas partes de nuestro código que está relacionado (y por lo tanto está usando las mismas variables) dentro de un IIFE, todas las variables y nombres de funciones están dentro de los paréntesis de funciones del IIFE . Esto reduce las posibilidades de nombrar conflictos y le permite nombrarlos de forma más descuidada (por ejemplo, no es necesario que los prefije).
Esta función se llama función de auto invocación. Una función de auto invocación (también llamada autoejecutable) es una función sin nombre (anónima) que se invoca (llama) inmediatamente después de su definición. Leer más aquí
Lo que hacen estas funciones es que cuando se define la función, se llama a la función de inmediato, lo que ahorra tiempo y líneas de código adicionales (en comparación con llamarla en una línea separada).
Aquí hay un ejemplo:
(function() {
var x = 5 + 4;
console.log(x);
})();
Esta es una explicación más profunda de por qué usaría esto:
"La razón principal para usar un IIFE es obtener privacidad de los datos. Debido a que las variables de alcance var de JavaScript a su función de contención, el mundo exterior no puede acceder a las variables declaradas dentro del IIFE".
Es una expresión de función, significa Expresión de función invocada inmediatamente (IIFE). IIFE es simplemente una función que se ejecuta inmediatamente después de su creación. Entonces, en lugar de que la función tenga que esperar hasta que se llame para ejecutarse, IIFE se ejecuta de inmediato. Construyamos el IIFE con el ejemplo. Supongamos que tenemos una función de agregar que toma dos enteros como argumentos y devuelve la suma. Hagamos que la función de agregar se convierta en un IIFE,
Paso 1: definir la función
function add (a, b){
return a+b;
}
add(5,5);
Paso 2: llame a la función envolviendo la declaración de función completa entre paréntesis
(function add (a, b){
return a+b;
})
//add(5,5);
Paso 3: para invocar la función inmediatamente, simplemente elimine el texto 'agregar' de la llamada.
(function add (a, b){
return a+b;
})(5,5);
La razón principal para usar un IFFE es preservar un ámbito privado dentro de su función. Dentro de su código javascript desea asegurarse de que no está anulando ninguna variable global. A veces puede definir accidentalmente una variable que anula una variable global. Probemos con el ejemplo. supongamos que tenemos un archivo html llamado iffe.html y los códigos dentro de la etiqueta body son-
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
Bueno, el código anterior se ejecutará sin ninguna pregunta, ahora suponga que rechazó una variable denominada documento accidental o intencionalmente.
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
const document = "hi there";
console.log(document);
</script>
</body>
terminará en un SyntaxError : redeclaración de documento de propiedad global no configurable.
Pero si su deseo es desclear un documento de nombre variable, puede hacerlo usando IFFE.
<body>
<div id = 'demo'></div>
<script>
(function(){
const document = "hi there";
this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
console.log(document);
})();
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
Salida:
Probemos con otro ejemplo, supongamos que tenemos un objeto de calculadora como abajo-
<body>
<script>
var calculator = {
add:function(a,b){
return a+b;
},
mul:function(a,b){
return a*b;
}
}
console.log(calculator.add(5,10));
</script>
</body>
Bueno, está funcionando a las mil maravillas, ¿y si accidentalmente reasignemos el valor del objeto de la calculadora?
<body>
<script>
var calculator = {
add:function(a,b){
return a+b;
},
mul:function(a,b){
return a*b;
}
}
console.log(calculator.add(5,10));
calculator = "scientific calculator";
console.log(calculator.mul(5,5));
</script>
</body>
sí, terminará con un TypeError: calculator.mul no es una función iffe.html
Pero con la ayuda de IFFE podemos crear un ámbito privado donde podemos crear otra calculadora de nombre de variable y usarla;
<body>
<script>
var calculator = {
add:function(a,b){
return a+b;
},
mul:function(a,b){
return a*b;
}
}
var cal = (function(){
var calculator = {
sub:function(a,b){
return a-b;
},
div:function(a,b){
return a/b;
}
}
console.log(this.calculator.mul(5,10));
console.log(calculator.sub(10,5));
return calculator;
})();
console.log(calculator.add(5,10));
console.log(cal.div(10,5));
</script>
</body>
Creo que los 2 conjuntos de paréntesis lo hacen un poco confuso, pero vi otro uso en el ejemplo de Google, usaron algo similar, espero que esto te ayude a entender mejor:
var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);
así que si windows.app
no está definido, entonces window.app = {}
se ejecuta inmediatamente, por lo que window.app
se asigna {}
durante la evaluación de la condición, por lo que el resultado es ambos app
y window.app
ahora se convierte {}
, por lo que la salida de la consola es:
Object {}
Object {}
Normalmente, el código JavaScript tiene un alcance global en la aplicación. Cuando declaramos la variable global en él, existe la posibilidad de utilizar 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 mediante el uso de la función de invocación inmediata, esta expresión es una expresión de ejecución automática. expresión , la variable global será como el ámbito local y la variable local.
Dos formas de 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, " aplicación var " es una variable local ahora.