Eu estava lendo alguns posts sobre fechamentos e vi isso em todos os lugares, mas não há uma explicação clara de como funciona - sempre que me disseram para usá-lo ...:
// Create a new anonymous function, to use as a wrapper
(function(){
// The variable that would, normally, be global
var msg = "Thanks for visiting!";
// Binding a new function to a global object
window.onunload = function(){
// Which uses the 'hidden' variable
alert( msg );
};
// Close off the anonymous function and execute it
})();
Ok, vejo que vamos criar uma nova função anônima e depois executá-la. Então, depois disso, esse código simples deve funcionar (e funciona):
(function (msg){alert(msg)})('SO');
Minha pergunta é que tipo de mágica acontece aqui? Eu pensei que quando escrevi:
(function (msg){alert(msg)})
então uma nova função sem nome seria criada como a função "" (msg) ...
mas então por que isso não funciona?
(function (msg){alert(msg)});
('SO');
Por que ele precisa estar na mesma linha?
Você poderia me indicar algumas postagens ou me dar uma explicação?
(function (msg){alert(msg)})('SO');
funciona completamente por conta própria. Não tem nada a ver com a outra função anônima que você postou antes dela. Essas são duas funções anônimas completamente separadas. Você precisa invocar uma função anônima imediatamente porque ela não tem nome e não pode ser referenciada posteriormente.Respostas:
Solte o ponto e vírgula após a definição da função.
Acima deve funcionar.
Página DEMO: https://jsfiddle.net/e7ooeq6m/
Eu discuti esse tipo de padrão neste post:
jQuery e $ perguntas
EDITAR:
Se você observar as especificações de script do ECMA , existem três maneiras de definir uma função. (Página 98, Seção 13, Definição de função)
1. Usando o construtor Function
2. Usando declaração de função.
3. Expressão de Função
Então você pode perguntar: qual é a diferença entre declaração e expressão?
Da especificação de script ECMA:
Se você perceber, 'identificador' é opcional para a expressão da função. E quando você não fornece um identificador, você cria uma função anônima. Isso não significa que você não pode especificar um identificador.
Isso significa que seguir é válido.
Um ponto importante a ser observado é que você pode usar 'mySum' apenas dentro do corpo da função mySum, não fora. Veja o seguinte exemplo:
Demonstração ao vivo
Compare isso com
Armado com esse conhecimento, vamos tentar analisar seu código.
Quando você tem código como,
Você criou uma expressão de função. E você pode executar esta expressão de função envolvendo-a entre parênteses.
fonte
É chamada de função auto-invocada.
O que você está fazendo quando chama
(function(){})
retornando um objeto de função. Quando você anexa()
a ele, ele é chamado e qualquer coisa no corpo é executada. A;
denota o fim da instrução, é por isso que a segunda invocação falha.fonte
Uma coisa que achei confusa é que os "()" são operadores de agrupamento.
Aqui está sua função declarada básica.
Ex. 1:
Funções são objetos e podem ser agrupados. Então, vamos jogar parens em torno da função.
Ex. 2:
Agora, em vez de declarar e chamar imediatamente a mesma função, podemos usar a substituição básica para declará-la como a chamamos.
Ex. 3)
Finalmente, não precisamos desse foo extra porque não estamos usando o nome para chamá-lo! Funções podem ser anônimas.
Ex. 4)
Para responder à sua pergunta, consulte o Exemplo 2. Sua primeira linha declara alguma função sem nome e a agrupa, mas não a chama. A segunda linha agrupa uma sequência. Ambos não fazem nada. (Primeiro exemplo de Vincent.)
Mas
fonte
Uma função anônima não é uma função com o nome "". É simplesmente uma função sem nome.
Como qualquer outro valor em JavaScript, uma função não precisa de um nome para ser criado. Embora seja muito mais útil vinculá-lo a um nome como qualquer outro valor.
Mas, como qualquer outro valor, às vezes você deseja usá-lo sem vinculá-lo a um nome. Esse é o padrão de auto-invocação.
Aqui está uma função e um número, não vinculados, eles não fazem nada e nunca podem ser usados:
Portanto, temos que armazená-los em uma variável para poder usá-los, assim como qualquer outro valor:
Você também pode usar açúcar sintático para vincular a função a uma variável:
Mas se não for necessário nomeá-los e levar a mais confusão e menos legibilidade, você poderá usá-los imediatamente.
Aqui, minha função e meus números não estão vinculados a uma variável, mas ainda podem ser usados.
Dito assim, parece que a função auto-invocadora não tem valor real. Mas você deve ter em mente que o delimitador de escopo do JavaScript é a função e não o bloco ({}).
Portanto, uma função de auto-chamada realmente tem o mesmo significado que um bloco C ++, C # ou Java. O que significa que a variável criada dentro não "vazará" fora do escopo. Isso é muito útil em JavaScript para não poluir o escopo global.
fonte
É assim que o JavaScript funciona. Você pode declarar uma função nomeada:
E chame:
Ou, você pode declarar uma função anônima:
E chame isso:
Ou, você nunca pode vincular a função a um nome:
Funções também podem retornar funções:
Não vale nada que quaisquer variáveis definidas com "var" no corpo de
make_foo
sejam fechadas por cada função retornada pormake_foo
. Este é um fechamento e significa que qualquer alteração feita no valor por uma função será visível por outra.Isso permite que você encapsule informações, se desejar:
É exatamente como quase todas as linguagens de programação, exceto Java, funcionam.
fonte
O código que você mostra,
consistem em duas declarações. A primeira é uma expressão que gera um objeto de função (que será então coletado como lixo porque não é salvo). A segunda é uma expressão que produz uma string. Para aplicar a função à string, você precisa passar a string como argumento para a função quando ela é criada (que você também mostra acima), ou será necessário realmente armazenar a função em uma variável, para que você possa aplique-o posteriormente, à sua vontade. Igual a:
Observe que, armazenando uma função anônima (uma função lambda) em uma variável, você está efetivamente dando um nome a ela. Portanto, você também pode definir uma função regular:
fonte
Em resumo dos comentários anteriores:
quando não atribuído a uma variável, gera um erro de sintaxe. O código é analisado como uma instrução de função (ou definição), que torna os parênteses de fechamento sintaticamente incorretos. Adicionar parênteses em torno da parte da função informa ao intérprete (e programador) que esta é uma expressão (ou chamada) de função, como em
Essa é uma função de auto-chamada, o que significa que é criada anonimamente e é executada imediatamente porque a chamada ocorre na mesma linha em que é declarada. Esta função auto-invocando é indicado com a sintaxe familiar para chamar uma função sem argumentos, além de parênteses adicionado ao redor do nome da função:
(myFunction)();
.Há uma boa sintaxe da função JavaScript da discussão sobre SO .
fonte
Esta resposta não está estritamente relacionada à pergunta, mas você pode estar interessado em descobrir que esse tipo de recurso de sintaxe não é específico para funções. Por exemplo, sempre podemos fazer algo assim:
Relacionado a funções. Como eles são objetos, que herdam do Function.prototype, podemos fazer coisas como:
E você sabe, nem precisamos rodear funções entre parênteses para executá-las. De qualquer forma, desde que tentemos atribuir o resultado a uma variável.
Outra coisa que você pode fazer com as funções, assim que as declara, é invocar o
new
operador sobre elas e obter um objeto. Os seguintes são equivalentes:fonte
Há mais uma propriedade que a função JavaScript possui. Se você deseja chamar a mesma função anônima recursivamente.
fonte
Meu entendimento da pergunta do autor da pergunta é tal que:
Como essa mágica funciona:
Eu posso estar errado. No entanto, a prática usual com a qual as pessoas estão familiarizadas é:
A razão é tal que o JavaScript entre parênteses AKA
()
, não pode conter instruções e, quando o analisador encontra a palavra-chave function, ele sabe analisá-la como uma expressão de função e não como uma declaração de função.Fonte: postagem no blog Expressão de Função Imediatamente Invocada (IIFE)
fonte
exemplos sem colchetes:
(este é o único uso real de void, afaik)
ou
ou
trabalhar também. a
void
está a causar a expressão para avaliar, assim como a atribuição e a explosão. o último trabalha com~
,+
,-
,delete
,typeof
, alguns dos operadores unários (void
é um bem). não está trabalhando++
,--
por causa da exigência de uma variável.a quebra de linha não é necessária.
fonte
delete
funciona. mesmo com'use strict';
. isso também funciona:delete (3 + 4);
É uma função anônima de execução automática. O primeiro conjunto de colchetes contém as expressões a serem executadas e o segundo conjunto de colchetes executa essas expressões.
Peter Michaux discute a diferença em Um Par Importante de Parênteses .
É uma construção útil ao tentar ocultar variáveis do namespace pai. Todo o código dentro da função está contido no escopo privado da função, o que significa que não pode ser acessado de fora da função, tornando-a verdadeiramente privada.
Vejo:
fonte
Outro ponto de vista
Primeiro, você pode declarar uma função anônima:
Então você chama:
Porque foo = function (msg) {alert (msg);} para que você possa substituir foo como:
Mas você deve agrupar toda a função anônima dentro de par de chaves para evitar erros de sintaxe da declaração de função ao analisar. Então nós temos,
Dessa forma, é fácil entender para mim.
fonte
Quando você fez:
Você encerrou a função antes
('SO')
por causa do ponto e vírgula. Se você acabou de escrever:Vai funcionar.
Exemplo de trabalho: http://jsfiddle.net/oliverni/dbVjg/
fonte
A simples razão pela qual não funciona não é por causa da
;
indicação do fim da função anônima. Isso ocorre porque, sem o()
término de uma chamada de função, não é uma chamada de função. Isso é,Se você ligar,
result = help();
é uma chamada para uma função e retornará true.Se você ligar
result = help;
não é uma ligação. É uma tarefa em que a ajuda é tratada como dados a serem atribuídos ao resultado.O que você fez foi declarar / instanciar uma função anônima adicionando o ponto-e-vírgula,
e tentei chamá-lo em outra instrução usando apenas parênteses ... Obviamente, porque a função não tem nome, mas isso não funcionará:
O intérprete vê os parênteses na segunda linha como uma nova instrução / instrução e, portanto, não funciona, mesmo que você tenha feito assim:
Ainda não funciona, mas funciona quando você remove o ponto-e-vírgula porque o intérprete ignora os espaços em branco e os carros e vê o código completo como uma instrução.
Conclusão: uma chamada de função não é uma chamada de função sem a
()
extremidade, a menos que sob condições específicas, como ser invocada por outra função, ou seja, onload = 'help' execute a função help mesmo que os parênteses não tenham sido incluídos. Eu acredito que setTimeout e setInterval também também permitem esse tipo de chamada de função, e também acredito que o intérprete adiciona os parênteses nos bastidores de qualquer maneira, o que nos leva de volta a "uma chamada de função não é uma chamada de função sem os parênteses".fonte
Esse é um método comum de usar uma função anônima como um fechamento usado por muitas estruturas JavaScript.
Essa função chamada é automaticamente quando o código é compilado.
Se colocar
;
na primeira linha, o compilador tratou como duas linhas diferentes. Portanto, você não pode obter os mesmos resultados acima.Isso também pode ser escrito como:
Para mais detalhes, consulte JavaScript / Funções Anônimas .
fonte
Funções anônimas são declaradas dinamicamente em tempo de execução. Eles são chamados de funções anônimas porque não recebem um nome da mesma maneira que as funções normais.
Funções anônimas são declaradas usando o operador function em vez da declaração da função. Você pode usar o operador de função para criar uma nova função sempre que for válido colocar uma expressão. Por exemplo, você pode declarar uma nova função como parâmetro para uma chamada de função ou atribuir uma propriedade de outro objeto.
Aqui está um exemplo típico de uma função nomeada:
função flyToTheMoon () {alert ("Zoom! Zoom! Zoom!"); } flyToTheMoon (); Aqui está o mesmo exemplo criado como uma função anônima:
var flyToTheMoon = function () {alert ("Zoom! Zoom! Zoom!"); } flyToTheMoon ();
Para detalhes, leia aqui:
http://helephant.com/2008/08/23/javascript-anonymous-functions/
fonte
O IIFE simplesmente compartimenta a função e oculta a
msg
variável para não "poluir" o espaço para nome global. Na realidade, mantenha-o simples e faça o seguinte, a menos que você esteja construindo um site de um bilhão de dólares.Você pode namespace sua
msg
propriedade usando um padrão de módulo revelador, como:fonte
As funções anônimas devem ser tratadas de uma só vez, onde você define uma função em tempo real para gerar uma saída de você a partir de uma entrada que você está fornecendo. Exceto que você não forneceu a entrada. Em vez disso, você escreveu algo na segunda linha ('SO'); - uma declaração independente que não tem nada a ver com a função. O que você esperava? :)
fonte
var foo = function() {};
. Tudo o resto está bem.