En javascript, ¿cuándo quieres usar esto?
(function(){
//Bunch of code...
})();
Más allá de esto:
//Bunch of code...
En javascript, ¿cuándo quieres usar esto?
(function(){
//Bunch of code...
})();
Más allá de esto:
//Bunch of code...
Respuestas:
Se trata de alcance variable. Las variables declaradas en la función de ejecución automática están, por defecto, solo disponibles para codificar dentro de la función de ejecución automática. Esto permite que el código se escriba sin preocuparse de cómo se nombran las variables en otros bloques de código JavaScript.
Por ejemplo, como se menciona en un comentario de Alexander :
(function() {
var foo = 3;
console.log(foo);
})();
console.log(foo);
Esto primero registrará 3
y luego arrojará un error en el siguiente console.log
porque foo
no está definido.
var
, así ...function(){ foo=3;}
:? Establecería una variable global, ¿verdad?
function(){ var foo = 3; alert(foo); }; alert(foo);
así que todavía no lo entiendo
Simplista. Muy normal, es casi reconfortante:
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
Sin embargo, ¿qué sucede si incluyo una biblioteca de JavaScript realmente útil en mi página que traduce los caracteres avanzados en sus representaciones de nivel base?
¿Esperar lo?
Quiero decir, si alguien teclea un personaje con algún tipo de acento, pero solo quiero caracteres 'ingleses' AZ en mi programa. Bueno ... los caracteres españoles 'ñ' y franceses 'é' pueden traducirse en caracteres base de 'n' y 'e'.
Entonces, una persona agradable ha escrito un conversor de caracteres completo que puedo incluir en mi sitio ... Lo incluyo.
Un problema: tiene una función llamada 'nombre' igual que mi función.
Esto es lo que se llama colisión. Tenemos dos funciones declaradas en el mismo alcance con el mismo nombre. Queremos evitar esto.
Por lo tanto, necesitamos analizar nuestro código de alguna manera.
La única forma de abarcar el código en javascript es envolverlo en una función:
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
Eso podría resolver nuestro problema. Ahora todo está cerrado y solo se puede acceder desde nuestras llaves de apertura y cierre.
Tenemos una función en una función ... que es extraño de ver, pero totalmente legal.
Solo un problema. Nuestro código no funciona. ¡Nuestra variable userName nunca se repite en la consola!
Podemos resolver este problema agregando una llamada a nuestra función después de nuestro bloque de código existente ...
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
main();
¡O antes!
main();
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
Una preocupación secundaria: ¿cuáles son las posibilidades de que el nombre 'main' aún no se haya utilizado? ... muy, muy delgado.
Necesitamos más alcance. Y alguna forma de ejecutar automáticamente nuestra función main ().
Ahora llegamos a las funciones de ejecución automática (o autoejecutable, autoejecutable, lo que sea).
((){})();
La sintaxis es incómoda como el pecado. Sin embargo, funciona.
Cuando ajusta una definición de función entre paréntesis e incluye una lista de parámetros (¡otro conjunto o paréntesis!), Actúa como una llamada de función .
Así que echemos un vistazo a nuestro código nuevamente, con alguna sintaxis autoejecutable:
(function main() {
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
)();
Entonces, en la mayoría de los tutoriales que lees, ahora serás bombardeado con el término 'autoejecutable anónimo' o algo similar.
Después de muchos años de desarrollo profesional, le recomiendo encarecidamente que nombre todas las funciones que escriba con fines de depuración.
Cuando algo sale mal (y lo hará), verificará la traza inversa en su navegador. Siempre es más fácil reducir los problemas de código cuando las entradas en el seguimiento de la pila tienen nombres!
Enormemente largo aliento y espero que ayude!
:)
La autoinvocación (también conocida como autoinvocación) es cuando una función se ejecuta inmediatamente después de su definición. Este es un patrón central y sirve como base para muchos otros patrones de desarrollo de JavaScript.
Soy un gran fan :) porque:
Enormemente - (¿Por qué deberías decir que es bueno?)
Más aquí .
Espaciado de nombres. Los ámbitos de JavaScript son de nivel de función.
No puedo creer que ninguna de las respuestas mencione globales implícitos.
El (function(){})()
constructo no protege contra los globales implícitos, lo que para mí es la mayor preocupación, consulte http://yuiblog.com/blog/2006/06/01/global-domination/
Básicamente, el bloque de función se asegura de que todos los "variables globales" dependientes que definió estén confinados en su programa, no lo protege contra la definición de globales implícitos. JSHint o similares pueden proporcionar recomendaciones sobre cómo defenderse contra este comportamiento.
La var App = {}
sintaxis más concisa proporciona un nivel de protección similar y puede incluirse en el bloque de funciones cuando se encuentra en páginas "públicas". (vea Ember.js o SproutCore para ejemplos del mundo real de bibliotecas que usan esta construcción)
En cuanto a las private
propiedades, están sobrevaloradas a menos que esté creando un marco público o biblioteca, pero si necesita implementarlas, Douglas Crockford tiene algunas buenas ideas.
He leído todas las respuestas, aquí falta algo muy importante , BESO. Hay 2 razones principales por las que necesito funciones anónimas autoejecutables, o mejor dicho " Expresión de función invocada de inmediato (IIFE) ":
El primero se ha explicado muy bien. Para el segundo, estudie el siguiente ejemplo:
var MyClosureObject = (function (){
var MyName = 'Michael Jackson RIP';
return {
getMyName: function () { return MyName;},
setMyName: function (name) { MyName = name}
}
}());
Atención 1: no estamos asignando una función a MyClosureObject
, más aún el resultado de invocar esa función . Tenga en cuenta ()
en la última línea.
Atención 2: lo que además debe saber sobre las funciones en Javascript es que las funciones internas tienen acceso a los parámetros y variables de las funciones, que están definidas dentro.
Probemos algunos experimentos:
Puedo MyName
usar getMyName
y funciona:
console.log(MyClosureObject.getMyName());
// Michael Jackson RIP
El siguiente enfoque ingenuo no funcionaría:
console.log(MyClosureObject.MyName);
// undefined
Pero puedo establecer otro nombre y obtener el resultado esperado:
MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName());
// George Michael RIP
Editar: en el ejemplo anterior MyClosureObject
está diseñado para usarse sin el new
prefijo, por lo tanto, por convención, no debe escribirse en mayúscula.
¿Hay un parámetro y el "Bunch of code" devuelve una función?
var a = function(x) { return function() { document.write(x); } }(something);
Cierre. El valor de something
se usa por la función asignada a a
. something
podría tener algún valor variable (para bucle) y cada vez que a tiene una nueva función.
var x = something;
en el exterior sobre la función x
como parámetro, sin embargo: imo que es más fácil de leer de esta manera ...
x
y depende directamente del alcance léxico, es decir document.write(something)
...
Alcance de aislamiento, tal vez. Para que las variables dentro de la declaración de función no contaminen el espacio de nombres externo.
Por supuesto, en la mitad de las implementaciones de JS que existen, de todos modos lo harán.
Aquí hay un ejemplo sólido de cómo una función anónima autoinvocatoria podría ser útil.
for( var i = 0; i < 10; i++ ) {
setTimeout(function(){
console.log(i)
})
}
Salida: 10, 10, 10, 10, 10...
for( var i = 0; i < 10; i++ ) {
(function(num){
setTimeout(function(){
console.log(num)
})
})(i)
}
Salida: 0, 1, 2, 3, 4...
let
lugar del var
primer caso estará bien.
Dado que las funciones en Javascript son objetos de primera clase, al definirlo de esa manera, define efectivamente una "clase" muy parecida a C ++ o C #.
Esa función puede definir variables locales y tener funciones dentro de ella. Las funciones internas (métodos de instancia efectivos) tendrán acceso a las variables locales (variables de instancia efectivas), pero estarán aisladas del resto del script.
Función auto invocada en javascript:
Una expresión autoinvocatoria se invoca (inicia) automáticamente, sin ser llamada. Una expresión autoinvocatoria se invoca justo después de su creación. Esto se usa básicamente para evitar conflictos de nombres y para lograr la encapsulación. Las variables u objetos declarados no son accesibles fuera de esta función. Para evitar los problemas de minimización (filename.min) use siempre la función autoejecutada.
Las funciones de ejecución automática se utilizan para administrar el alcance de una variable.
El alcance de una variable es la región de su programa en la que se define.
Una variable global tiene alcance global; se define en todas partes en su código JavaScript y se puede acceder desde cualquier lugar dentro del script, incluso en sus funciones. Por otro lado, las variables declaradas dentro de una función se definen solo dentro del cuerpo de la función. Son variables locales, tienen alcance local y solo se puede acceder dentro de esa función. Los parámetros de la función también cuentan como variables locales y se definen solo dentro del cuerpo de la función.
Como se muestra a continuación, puede acceder a la variable variable global dentro de su función y también observar que dentro del cuerpo de una función, una variable local tiene prioridad sobre una variable global con el mismo nombre.
var globalvar = "globalvar"; // this var can be accessed anywhere within the script
function scope() {
alert(globalvar);
localvar = "localvar" //can only be accessed within the function scope
}
scope();
Entonces, básicamente, una función de ejecución automática permite que el código se escriba sin preocuparse de cómo se nombran las variables en otros bloques de código javascript.
(function(){
var foo = {
name: 'bob'
};
console.log(foo.name); // bob
})();
console.log(foo.name); // Reference error
En realidad, la función anterior se tratará como expresión de función sin un nombre.
El objetivo principal de ajustar una función con paréntesis abiertos y cerrados es evitar contaminar el espacio global.
Las variables y funciones dentro de la expresión de la función se volvieron privadas (es decir) no estarán disponibles fuera de la función.
La respuesta corta es: para prevenir la contaminación del alcance global (o superior).
IIFE (Expresiones de funciones invocadas inmediatamente) es la mejor práctica para escribir scripts como complementos, complementos, scripts de usuario o cualquier script que se espere que funcione con los scripts de otras personas . Esto garantiza que cualquier variable que defina no produzca efectos no deseados en otros scripts.
Esta es la otra forma de escribir la expresión IIFE. Personalmente prefiero este siguiente método:
void function() {
console.log('boo!');
// expected output: "boo!"
}();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
Según el ejemplo anterior, está muy claro que IIFE también puede afectar la eficiencia y el rendimiento, porque la función que se espera que se ejecute solo una vez se ejecutará una vez y luego se descargará en el vacío para siempre . Esto significa que la declaración de función o método no permanece en la memoria.
void
antes. Me gusta.
Primero debes visitar MDN IIFE , ahora algunos puntos sobre esto
Parece que esta pregunta ha sido respondida lista, pero de todos modos publicaré mi opinión.
Sé cuándo me gusta usar funciones de ejecución automática.
var myObject = {
childObject: new function(){
// bunch of code
},
objVar1: <value>,
objVar2: <value>
}
La función me permite usar un código adicional para definir los atributos y propiedades de childObjects para un código más limpio, como establecer variables de uso común o ejecutar ecuaciones matemáticas; Oh! o comprobación de errores. en lugar de limitarse a la sintaxis de instanciación de objetos anidados de ...
object: {
childObject: {
childObject: {<value>, <value>, <value>}
},
objVar1: <value>,
objVar2: <value>
}
La codificación en general tiene muchas formas oscuras de hacer muchas de las mismas cosas, haciendo que te preguntes, "¿Por qué molestarse?" Pero siguen apareciendo nuevas situaciones en las que ya no puede confiar solo en los principios básicos / básicos.
Dada su simple pregunta: "En javascript, ¿cuándo desea utilizar esto: ..."
Me gustan las respuestas de @ken_browning y @ sean_holding, pero aquí hay otro caso de uso que no veo mencionado:
let red_tree = new Node(10);
(async function () {
for (let i = 0; i < 1000; i++) {
await red_tree.insert(i);
}
})();
console.log('----->red_tree.printInOrder():', red_tree.printInOrder());
donde Node.insert es una acción asincrónica.
No puedo simplemente llamar en espera sin la palabra clave asíncrona en la declaración de mi función, y no necesito una función con nombre para su uso posterior, pero necesito esperar esa llamada de inserción o necesito otras características más completas (¿quién sabe?) .
IIRC te permite crear propiedades y métodos privados.