Eu sabia o que isso significava, mas agora estou lutando ...
Isso é basicamente dizer document.onload
?
(function () {
})();
Eu sabia o que isso significava, mas agora estou lutando ...
Isso é basicamente dizer document.onload
?
(function () {
})();
Respostas:
É uma expressão de função chamada imediatamente , ou IIFE, para abreviar. Ele é executado imediatamente após ser criado.
Não tem nada a ver com qualquer manipulador de eventos para eventos (como document.onload
).
Considere a parte dentro do primeiro par de parênteses: .... é uma expressão de função regular. Em seguida, observe o último par , que normalmente é adicionado a uma expressão para chamar uma função; neste caso, nossa expressão anterior.(function(){})();
(function(){})();
Esse padrão é frequentemente usado ao tentar evitar poluir o espaço para nome global, porque todas as variáveis usadas no IIFE (como em qualquer outra função normal ) não são visíveis fora do seu escopo.
É por isso que, talvez, você tenha confundido essa construção com um manipulador de eventos para window.onload
, porque geralmente é usado assim:
(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)
Correção sugerida por Guffa :
A função é executada logo após ser criada, não depois de analisada. O bloco de script inteiro é analisado antes de qualquer código nele ser executado. Além disso, o código de análise não significa automaticamente que ele é executado; se, por exemplo, o IIFE estiver dentro de uma função, ele não será executado até que a função seja chamada.
Atualização Como esse é um tópico bastante popular, vale a pena mencionar que os IIFE também podem ser escritos com a função de seta do ES6 (como Gajus apontou em um comentário ):
((foo) => {
// do something with foo here foo
})('foo value')
function(){ var foo = '5'; }
É apenas uma função anônima que é executada logo após ser criada.
É como se você o atribuísse a uma variável e a usasse logo depois, apenas sem a variável:
var f = function () {
};
f();
No jQuery, existe uma construção semelhante em que você pode estar pensando:
$(function(){
});
Essa é a forma abreviada de vincular o ready
evento:
$(document).ready(function(){
});
Mas as duas construções acima não são IIFE .
Uma expressão de função chamada imediatamente (IIFE) chama imediatamente uma função. Isso significa simplesmente que a função é executada imediatamente após a conclusão da definição.
Três formulações mais comuns:
// 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.');
}();
Se não houver requisitos especiais para seu valor de retorno, podemos escrever:
!function(){}(); // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}(); // => NaN
Como alternativa, pode ser:
~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();
Você pode até escrever:
new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required
31.new
'é sintaxe inválida
;(function(){}());
1 - 1
e pode fazer com a mesma facilidade true - function(){}
. É apenas uma coisa (um operador de subtração de infixos), mas com operandos diferentes, até sem sentido.
Ele declara uma função anônima e a chama:
(function (local_arg) {
// anonymous function
console.log(local_arg);
})(arg);
Isso significa executar imediatamente.
então se eu fizer:
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/
var val = (function(){
return 13 + 5;
})();
alert(val); //18
Essa construção é chamada Expressão de Função Invocada Imediatamente (IIFE), o que significa que é executada imediatamente. Pense nisso como uma função sendo chamada automaticamente quando o intérprete atingir essa função.
Caso de uso mais comum:
Um de seus casos de uso mais comuns é limitar o escopo de uma variável criada via var
. As variáveis criadas via var
têm um escopo limitado a uma função, de modo que essa construção (que é um invólucro de função em torno de determinado código) garantirá que seu escopo de variável não vaze para essa função.
No exemplo a seguir, count
não estará disponível fora da função chamada imediatamente, ou seja, o escopo de count
não vazará da função. Você deve obter um ReferenceError
, caso tente acessá-lo fora da função imediatamente invocada de qualquer maneira.
(function () {
var count = 10;
})();
console.log(count); // Reference Error: count is not defined
Alternativa ES6 (recomendada)
No ES6, agora podemos ter variáveis criadas via let
e const
. Ambos têm escopo de bloco (diferente var
do escopo de função).
Portanto, em vez de usar essa construção complexa de IIFE para o caso de uso mencionado acima, agora você pode escrever um código muito mais simples para garantir que o escopo de uma variável não vaze do bloco desejado.
{
let count = 10;
}
console.log(count); // ReferenceError: count is not defined
Neste exemplo, costumávamos let
definir a count
variável que count
limita o bloco de código que criamos com os colchetes {...}
.
Eu chamo de "Cadeia Curly".
(function () {
})();
Isso é chamado de IIFE (expressão de função chamada imediatamente). Um dos famosos padrões de design JavaScript, é o coração e a alma do padrão moderno do módulo. Como o nome sugere, ele é executado imediatamente após ser criado. Esse padrão cria um escopo de execução isolado ou privado.
O JavaScript anterior ao ECMAScript 6 usava o escopo lexical; portanto, o IIFE era usado para simular o escopo do bloco. (Com o escopo do bloco ECMAScript 6 é possível com a introdução das palavras let
- const
chave e .)
Referência para problema com o escopo lexical
Simule o escopo do bloco com IIFE
A vantagem de usar IIFE de desempenho é a capacidade de passar objetos globais comumente usados como window
, document
, etc. como um argumento, reduzindo a pesquisa de escopo. (Lembre-se de que o JavaScript procura propriedades no escopo local e sobe a cadeia até o escopo global). Portanto, acessar objetos globais no escopo local reduz o tempo de pesquisa como abaixo.
(function (globalObj) {
//Access the globalObj
})(window);
Não, essa construção apenas cria um escopo para nomeação. Se você o quebrar em partes, poderá ver que possui um
(...)();
Essa é uma invocação de função. Dentro dos parênteses você tem:
function() {}
Essa é uma função anônima. Tudo o que é declarado com var dentro da construção será visível apenas dentro da mesma construção e não poluirá o namespace global.
Esta é uma expressão de função chamada imediatamente em Javascript:
Para entender o IIFE em JS, vamos dividir:
a = 10 output = 10 (1+3) output = 4
// Function Expression var greet = function(name){ return 'Namaste' + ' ' + name; } greet('Santosh');
Como a expressão da função funciona:
- Quando o mecanismo JS é executado pela primeira vez (Contexto de Execução - Criar Fase), essa função (no lado direito de = acima) não é executada ou armazenada na memória. A variável 'greet' é atribuída ao valor 'indefinido' pelo mecanismo JS.
- Durante a execução (contexto de execução - fase de execução), o objeto de função é criado em tempo real ( ainda não foi executado ), é atribuído à variável 'greet' e pode ser chamado usando 'greet (' somename ')'.
3. Expressão de Função Invocada Imediatamente:
Exemplo:
// IIFE
var greeting = function(name) {
return 'Namaste' + ' ' + name;
}('Santosh')
console.log(greeting) // Namaste Santosh.
Como funciona o IIFE :
- Observe o '()' imediatamente após a declaração da função. Todo objeto de função tem uma propriedade 'CODE' anexada, que pode ser chamada. E podemos chamá-lo (ou invocá-lo) usando chaves '()'.
- Então aqui, durante a execução (Contexto de Execução - Fase de Execução), o objeto de função é criado e executado ao mesmo tempo
- Agora, a variável de saudação, em vez de ter o objeto de função, tem seu valor de retorno (uma string)
Caso típico de IIFE em JS:
O seguinte padrão IIFE é bastante usado.
// IIFE
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = 'Namaste';
console.log(greeting + ' ' + name);
})('Santosh');
Portanto, essa função é criada e executada ao mesmo tempo (IIFE).
Importante caso de uso para IIFE:
O IIFE mantém nosso código seguro.
- O IIFE, sendo uma função, possui seu próprio contexto de execução, ou seja, todas as variáveis criadas nele são locais para essa função e não são compartilhadas com o contexto de execução global.
Suponha que eu tenha outro arquivo JS (test1.js) usado no meu aplicativo junto com o iife.js (veja abaixo).
// 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'.
Portanto, o IIFE nos ajuda a escrever código seguro onde não estamos colidindo com objetos globais sem querer.
Essa é uma função anônima auto-invocadora .
Confira a explicação do W3Schools sobre uma função de auto-chamada .
Expressões de função podem ser "auto-invocadas".
Uma expressão de auto-chamada é invocada (iniciada) automaticamente, sem ser chamada.
As expressões de função serão executadas automaticamente se a expressão for seguida por ().
Você não pode auto-invocar uma declaração de função.
(function named(){console.log("Hello");}());
<- auto-executável chamado função
Esta é a função anônima auto-invocadora. É executado enquanto está definido. O que significa que esta função é definida e se chama imediatamente após a definição.
E a explicação da sintaxe é: A função dentro do primeiro ()
parêntese é a função que não tem nome e, no próximo ();
parêntese, você pode entender que ela é chamada no momento em que é definida. E você pode passar qualquer argumento neste segundo ()
parêntese que será capturado na função que está no primeiro parêntese. Veja este exemplo:
(function(obj){
// Do something with this obj
})(object);
Aqui, o 'objeto' que você está passando será acessível dentro da função por 'obj', como você o está agarrando na assinatura da função.
Começa aqui:
var b = 'bee';
console.log(b); // global
Coloque-o em uma função e ele não será mais global - seu objetivo principal.
function a() {
var b = 'bee';
console.log(b);
}
a();
console.log(b); // ReferenceError: b is not defined -- *as desired*
Chame a função imediatamente - oops:
function a() {
var b = 'bee';
console.log(b);
}(); // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'
Use os parênteses para evitar um erro de sintaxe:
(function a() {
var b = 'bee';
console.log(b);
})(); // OK now
Você pode deixar de fora o nome da função:
(function () { // no name required
var b = 'bee';
console.log(b);
})();
Não precisa ser mais complicado que isso.
Uncaught SyntaxError: Unexpected token )
mais do que qualquer menção à função de seta. Você poderia compartilhar um violino jogando o erro da função de seta?
Função anônima auto-executável. É executado assim que é criado.
Um exemplo curto e fictício em que isso é útil é:
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);
Portanto, em vez de criar uma lista a cada vez, você a cria apenas uma vez (menos sobrecarga).
As funções de execução automática são normalmente usadas para encapsular o contexto e evitar colusões de nomes. Qualquer variável que você definir dentro de (function () {..}) () não é global.
O código
var same_name = 1;
var myVar = (function() {
var same_name = 2;
console.log(same_name);
})();
console.log(same_name);
produz esta saída:
2
1
Ao usar essa sintaxe, você evita colidir com variáveis globais declaradas em outras partes do seu código JavaScript.
var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name);
Teria o mesmo resultado.
É chamado IIFE - Expressão de Função Imediatamente Invocada. Aqui está um exemplo para mostrar sua sintaxe e uso. É usado para escopo o uso de variáveis somente até a função e não além.
(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 (expressão de função chamada imediatamente) é uma função que é executada assim que o script é carregado e desaparece.
Considere a função abaixo escrita em um arquivo chamado iife.js
(function(){
console.log("Hello Stackoverflow!");
})();
Este código acima será executado assim que você carregar o iife.js e imprimirá ' Hello Stackoverflow! 'no console das ferramentas de desenvolvedor'.
Para obter uma explicação detalhada, consulte Expressão de função chamada imediatamente (IIFE)
Mais um caso de uso é a memorização em que um objeto de cache não é 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];
}
}
})();
Uma expressão de função chamada imediatamente (IIFE) é uma função que é executada assim que é criada. Não possui conexão com nenhum evento ou execução assíncrona. Você pode definir um IIFE como mostrado abaixo:
(function() {
// all your code here
// ...
})();
O primeiro par de parênteses function () {...} converte o código dentro dos parênteses em uma expressão. O segundo par de parênteses chama a função resultante da expressão.
Um IIFE
também pode ser descrito como uma função anônima auto-invocadora. Seu uso mais comum é limitar o escopo de uma variável feita via var ou encapsular o contexto para evitar colisões de nomes.
A razão pela qual as funções anônimas auto-evocativas são usadas é que elas nunca devem ser chamadas por outro código, uma vez que "configuram" o código que ISS deve ser chamado (além de dar espaço para funções e variáveis).
Em outras palavras, são como programas que "fazem aulas", no início do programa. Depois de instanciadas (automaticamente), as únicas funções disponíveis são as retornadas pela função anônima. No entanto, todas as outras " funções ocultas 'ainda estão lá, juntamente com qualquer estado (variáveis definidas durante a criação do escopo).
Muito legal.
O código a seguir:
(function () {
})();
é chamado de expressão de função imediatamente chamada (IIFE).
Isso é chamado de expressão de função porque o ( yourcode )
operador em Javascript a força a uma expressão. A diferença entre uma expressão de função e uma declaração de função é a seguinte:
// declaration:
function declaredFunction () {}
// expressions:
// storing function into variable
const expressedFunction = function () {}
// Using () operator, which transforms the function into an expression
(function () {})
Uma expressão é simplesmente um monte de código que pode ser avaliado em um único valor . No caso das expressões no exemplo acima, esse valor era um objeto de função única .
Depois de termos uma expressão que avalia um objeto de função, podemos chamar imediatamente o objeto de função com o ()
operador. Por exemplo:
(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
Quando estamos lidando com uma grande base de código e / ou quando estamos importando várias bibliotecas, a chance de nomear conflitos aumenta. Quando estamos escrevendo certas partes do nosso código que estão relacionadas (e, portanto, estão usando as mesmas variáveis) dentro de um IIFE, todas as variáveis e nomes de funções têm o escopo definido para os colchetes de função do IIFE . Isso reduz as chances de nomear conflitos e permite que você os nomeie com menos cuidado (por exemplo, você não precisa prefixá-los).
Essa função é chamada função auto-invocável. Uma função de auto-invocação (também chamada de auto-execução) é uma função sem nome (anônima) que é invocada (Chamada) imediatamente após sua definição. Leia mais aqui
O que essas funções fazem é que, quando a função é definida, a função é chamada imediatamente, o que economiza tempo e linhas extras de código (em comparação com chamá-la em uma linha separada).
Aqui está um exemplo:
(function() {
var x = 5 + 4;
console.log(x);
})();
Esta é uma explicação mais detalhada sobre por que você usaria isso:
"O principal motivo para usar um IIFE é obter a privacidade dos dados. Como as variáveis do JavaScript selecionam as variáveis para sua função de contenção, quaisquer variáveis declaradas no IIFE não podem ser acessadas pelo mundo exterior."
É uma expressão de função, significa Expressão de Função Invocada Imediatamente (IIFE). IIFE é simplesmente uma função que é executada logo após ser criada. Assim, como a função precisa esperar até que seja chamada para ser executada, o IIFE é executado imediatamente. Vamos construir o IIFE por exemplo. Suponha que tenhamos uma função add, que recebe dois números inteiros como args e retorna a soma, para que a função add seja transformada em um IIFE,
Etapa 1: definir a função
function add (a, b){
return a+b;
}
add(5,5);
Etapa 2: Chame a função envolvendo toda a declaração de função entre parênteses
(function add (a, b){
return a+b;
})
//add(5,5);
Etapa 3: para ativar a função imediatamente, remova o texto 'adicionar' da chamada.
(function add (a, b){
return a+b;
})(5,5);
O principal motivo para usar um IFFE é preservar um escopo privado dentro de sua função. Dentro do seu código javascript, você deseja garantir que não substitua nenhuma variável global. Às vezes, você pode definir acidentalmente uma variável que substitui uma variável global. Vamos tentar pelo exemplo. suponha que tenhamos um arquivo html chamado iffe.html e os códigos dentro da tag body estejam-
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
Bem, o código acima será executado sem qualquer pergunta, agora assuma que você decleard uma variável chamada documento acidental ou intencional.
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
const document = "hi there";
console.log(document);
</script>
</body>
você terminará em um SyntaxError : redeclaração de documento de propriedade global não configurável.
Mas se seu desejo é declear um nome de variável documet, você pode fazê-lo usando o 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>
Resultado:
Vamos tentar com outro exemplo, suponha que tenhamos um objeto de calculadora como abaixo
<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>
Bem, está funcionando como um encanto, e se acidentalmente atribuirmos novamente o valor do objeto da 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>
sim, você terminará com um TypeError: calculator.mul não é uma função iffe.html
Porém, com a ajuda do IFFE, podemos criar um escopo privado, onde podemos criar outra calculadora de nome de variável e usá-la;
<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>
Acho que os 2 conjuntos de colchetes o tornam um pouco confuso, mas vi outro uso no exemplo do Google, eles usaram algo semelhante, espero que isso ajude você a entender melhor:
var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);
portanto, se windows.app
não for definido, window.app = {}
será executado imediatamente, window.app
atribuído a ele {}
durante a avaliação da condição, para que o resultado seja ambos app
e window.app
agora se torne {}
, portanto, a saída do console é:
Object {}
Object {}
Normalmente, o código JavaScript tem escopo global no aplicativo. Quando declaramos uma variável global nela, há uma chance de usar a mesma variável duplicada em alguma outra área do desenvolvimento para algum outro propósito. Devido a essa duplicação, pode ocorrer algum erro. Portanto, podemos evitar essas variáveis globais usando a expressão de função de chamada imediata, essa expressão é uma expressão de execução automática. Quando criamos nosso código dentro desse IIFE expressão a variável global será como escopo local e variável local.
Duas maneiras de criar o IIFE
(function () {
"use strict";
var app = angular.module("myModule", []);
}());
OU
(function () {
"use strict";
var app = angular.module("myModule", []);
})();
No snippet de código acima, " var app " é uma variável local agora.