Em javascript, quando você deseja usar isso:
(function(){
//Bunch of code...
})();
por cima disto:
//Bunch of code...
Em javascript, quando você deseja usar isso:
(function(){
//Bunch of code...
})();
por cima disto:
//Bunch of code...
Respostas:
É tudo sobre escopo variável. As variáveis declaradas na função de execução automática, por padrão, estão disponíveis apenas para codificar na função de execução automática. Isso permite que o código seja gravado sem a preocupação de como as variáveis são nomeadas em outros blocos de código JavaScript.
Por exemplo, conforme mencionado em um comentário de Alexander :
(function() {
var foo = 3;
console.log(foo);
})();
console.log(foo);
Isso primeiro registra 3
e depois gera um erro no próximo, console.log
porque foo
não está definido.
var
, assim ...function(){ foo=3;}
:? Isso definiria uma variável global, certo?
function(){ var foo = 3; alert(foo); }; alert(foo);
Então, eu ainda não entendo
Simplista. Tão muito normal, é quase reconfortante:
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
No entanto, e se eu incluir uma biblioteca javascript realmente útil na minha página que traduza caracteres avançados em suas representações no nível base?
Espere o que?
Quero dizer, se alguém digitar um personagem com algum tipo de sotaque, mas eu só quero caracteres em 'inglês' AZ no meu programa? Bem ... os caracteres espanhol 'ñ' e francês 'é' podem ser traduzidos para caracteres base de 'n' e 'e'.
Então, alguém legal escreveu um abrangente conversor de caracteres que eu posso incluir no meu site ... eu o incluo.
Um problema: ele tem uma função chamada 'name' igual à minha função.
Isso é chamado de colisão. Temos duas funções declaradas no mesmo escopo com o mesmo nome. Queremos evitar isso.
Então, precisamos escopo nosso código de alguma forma.
A única maneira de escopo do código em javascript é envolvê-lo em uma função:
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;
}
}
Isso pode resolver o nosso problema. Agora tudo está fechado e só pode ser acessado de dentro de nossas chaves de abertura e fechamento.
Temos uma função em uma função ... que é estranha de se ver, mas totalmente legal.
Apenas um problema. Nosso código não funciona. Nossa variável userName nunca é ecoada no console!
Podemos resolver esse problema adicionando uma chamada à nossa função após o bloco 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();
Ou 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;
}
}
Uma preocupação secundária: quais são as chances de o nome 'principal' ainda não ter sido usado? ... muito, muito magro.
Precisamos de mais escopo. E alguma maneira de executar automaticamente nossa função main ().
Agora chegamos às funções de execução automática (ou auto-executáveis, auto-executáveis, qualquer que seja).
((){})();
A sintaxe é estranha como o pecado. No entanto, funciona.
Quando você coloca uma definição de função entre parênteses e inclui uma lista de parâmetros (outro conjunto ou parênteses!), Ela atua como uma chamada de função .
Então, vejamos nosso código novamente, com alguma sintaxe auto-executável:
(function main() {
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
)();
Portanto, na maioria dos tutoriais que você lê, agora você será bombardeado com o termo 'auto-execução anônima' ou algo semelhante.
Depois de muitos anos de desenvolvimento profissional, eu fortemente exortá-lo a nomear todas as funções que você escreve para fins de depuração.
Quando algo der errado (e ocorrerá), você verificará o backtrace no seu navegador. É sempre mais fácil restringir os problemas de código quando as entradas no rastreamento da pilha têm nomes!
Muito longo e espero que ajude!
:)
A auto-invocação (também conhecida como auto-invocação) ocorre quando uma função é executada imediatamente após sua definição. Esse é um padrão central e serve como base para muitos outros padrões de desenvolvimento JavaScript.
Eu sou um grande fã :) disso porque:
Enorme - (Por que você deveria dizer que é bom?)
Mais aqui .
Namespacing. Os escopos do JavaScript são de nível de função.
Não acredito que nenhuma das respostas menciona globais implícitas.
A (function(){})()
construção não protege contra globais implícitas, o que para mim é a maior preocupação, consulte http://yuiblog.com/blog/2006/06/01/global-domination/
Basicamente, o bloco de funções garante que todos os "vars globais" dependentes que você definiu estejam confinados ao seu programa, não o protegem contra a definição de globais implícitos. JSHint ou similar pode fornecer recomendações sobre como se defender contra esse comportamento.
A var App = {}
sintaxe mais concisa fornece um nível semelhante de proteção e pode ser agrupada no bloco de funções quando estiver em páginas 'públicas'. (consulte Ember.js ou SproutCore para obter exemplos reais de bibliotecas que usam essa construção)
No que diz respeito às private
propriedades, elas são superestimadas, a menos que você esteja criando uma estrutura ou biblioteca pública, mas se precisar implementá-las, Douglas Crockford tem algumas boas idéias.
Eu li todas as respostas, algo muito importante está faltando aqui , eu vou BEIJAR. Existem 2 razões principais, pelas quais eu preciso de Funções Anônimas Autoexecutáveis ou, melhor dizendo, " Expressão de Função Imediatamente Invocada (IIFE) ":
O primeiro foi explicado muito bem. Para o segundo, estude o seguinte exemplo:
var MyClosureObject = (function (){
var MyName = 'Michael Jackson RIP';
return {
getMyName: function () { return MyName;},
setMyName: function (name) { MyName = name}
}
}());
Atenção 1: Não estamos atribuindo uma função a MyClosureObject
, mais ainda, o resultado de invocar essa função . Estar ciente de()
última linha.
Atenção 2: O que você precisa saber adicionalmente sobre funções em Javascript é que as funções internas têm acesso aos parâmetros e variáveis das funções, elas são definidas dentro.
Vamos tentar algumas experiências:
Eu posso MyName
usar getMyName
e funciona:
console.log(MyClosureObject.getMyName());
// Michael Jackson RIP
A seguinte abordagem ingênua não funcionaria:
console.log(MyClosureObject.MyName);
// undefined
Mas posso definir outro nome e obter o resultado esperado:
MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName());
// George Michael RIP
Edit: No exemplo acima, ele MyClosureObject
foi projetado para ser usado sem o new
prefixo; portanto, por convenção, ele não deve ser capitalizado.
Existe um parâmetro e o "Grupo de códigos" retorna uma função?
var a = function(x) { return function() { document.write(x); } }(something);
Fecho. O valor de something
é usado pela função atribuída a a
. something
pode ter algum valor variável (para loop) e toda vez que uma tiver uma nova função.
var x = something;
na função exterior sobre x
como parâmetro, no entanto: imo que é mais legível desta forma ...
x
e depende directamente do escopo léxico, ou seja document.write(something)
...
Isolamento do escopo, talvez. Para que as variáveis dentro da declaração da função não poluam o espaço para nome externo.
É claro que, na metade das implementações de JS existentes, elas serão assim mesmo.
Aqui está um exemplo sólido de como uma função anônima auto-invocável pode ser útil.
for( var i = 0; i < 10; i++ ) {
setTimeout(function(){
console.log(i)
})
}
Resultado: 10, 10, 10, 10, 10...
for( var i = 0; i < 10; i++ ) {
(function(num){
setTimeout(function(){
console.log(num)
})
})(i)
}
Resultado: 0, 1, 2, 3, 4...
let
lugar do var
primeiro caso, tudo ficará bem.
Como as funções em Javascript são objetos de primeira classe, definindo-o dessa maneira, ele define efetivamente uma "classe" como C ++ ou C #.
Essa função pode definir variáveis locais e ter funções dentro dela. As funções internas (métodos de instância efetivamente) terão acesso às variáveis locais (variáveis de instância efetivamente), mas serão isoladas do restante do script.
Função auto-invocada em javascript:
Uma expressão de auto-chamada é invocada (iniciada) automaticamente, sem ser chamada. Uma expressão auto-invocadora é invocada logo após ser criada. Isso é basicamente usado para evitar conflitos de nomes e para obter encapsulamento. As variáveis ou objetos declarados não estão acessíveis fora desta função. Para evitar os problemas de minimização (filename.min), use sempre a função auto-executada.
A função de execução automática é usada para gerenciar o escopo de uma variável.
O escopo de uma variável é a região do seu programa em que está definida.
Uma variável global tem escopo global; ele é definido em qualquer lugar do seu código JavaScript e pode ser acessado de qualquer lugar do script, mesmo em suas funções. Por outro lado, variáveis declaradas dentro de uma função são definidas apenas dentro do corpo da função. São variáveis locais, têm escopo local e só podem ser acessadas nessa função. Os parâmetros da função também contam como variáveis locais e são definidos apenas dentro do corpo da função.
Como mostrado abaixo, você pode acessar a variável variável global dentro de sua função e também observar que, no corpo de uma função, uma variável local tem precedência sobre uma variável global com o mesmo nome.
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();
Então, basicamente, uma função de execução automática permite que o código seja escrito sem se preocupar com a forma como as variáveis são nomeadas em outros blocos de código javascript.
(function(){
var foo = {
name: 'bob'
};
console.log(foo.name); // bob
})();
console.log(foo.name); // Reference error
Na verdade, a função acima será tratada como expressão de função sem um nome.
O principal objetivo de agrupar uma função com parênteses próximos e abertos é evitar poluir o espaço global.
As variáveis e funções dentro da expressão da função tornaram-se privadas (ie), não estarão disponíveis fora da função.
A resposta curta é: para evitar a poluição do escopo Global (ou superior).
O IIFE (Expressões de Função Invocadas Imediatamente) é a melhor prática para escrever scripts como plug-ins, complementos, scripts de usuário ou qualquer outro script que possa funcionar com scripts de outras pessoas . Isso garante que qualquer variável que você defina não produza efeitos indesejados em outros scripts.
Essa é a outra maneira de escrever a expressão IIFE. Eu pessoalmente prefiro este método a seguir:
void function() {
console.log('boo!');
// expected output: "boo!"
}();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
A partir do exemplo acima, é muito claro que o IIFE também pode afetar a eficiência e o desempenho, porque a função que se espera que seja executada apenas uma vez será executada uma vez e depois despejada no vazio para sempre . Isso significa que a declaração de função ou método não permanece na memória.
void
antes. Eu gosto disso.
Primeiro você deve visitar o MDN IIFE . Agora, alguns pontos sobre isso
Parece que esta pergunta já foi respondida, mas postarei minha opinião de qualquer maneira.
Sei quando gosto de usar funções auto-executáveis.
var myObject = {
childObject: new function(){
// bunch of code
},
objVar1: <value>,
objVar2: <value>
}
A função permite que eu use algum código extra para definir os atributos e propriedades childObjects para um código mais limpo, como definir variáveis usadas com frequência ou executar equações matemáticas; Oh! ou verificação de erro. em vez de se limitar à sintaxe de instanciação de objetos aninhados de ...
object: {
childObject: {
childObject: {<value>, <value>, <value>}
},
objVar1: <value>,
objVar2: <value>
}
A codificação em geral tem muitas maneiras obscuras de fazer as mesmas coisas, fazendo você pensar: "Por que se preocupar?" Mas novas situações continuam surgindo, onde você não pode mais confiar apenas nos princípios básicos / principais.
Dada a sua pergunta simples: "Em javascript, quando você deseja usar isso: ..."
Eu gosto das respostas de @ken_browning e @ sean_holding, mas aqui está outro caso de uso que não vejo 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());
onde Node.insert é alguma ação assíncrona.
Não posso simplesmente chamar em espera sem a palavra-chave assíncrona na declaração da minha função, e não preciso de uma função nomeada para uso posterior, mas preciso aguardar a chamada de inserção ou preciso de outros recursos mais ricos (quem sabe?) .
IIRC permite criar propriedades e métodos privados.