Recentemente, estava comparando a versão atual do json2.js com a versão que tinha em meu projeto e notei uma diferença em como a expressão de função foi criada e executada automaticamente .
O código usado para envolver uma função anônima entre parênteses e, em seguida, executá-la,
(function () {
// code here
})();
mas agora ele envolve a função executada automaticamente entre parênteses.
(function () {
// code here
}());
Há um comentário do CMS na resposta aceita da sintaxe da função anônima encapsulada do Explain JavaScript que "ambos: (function(){})();
e (function(){}());
são válidos".
Eu queria saber qual é a diferença? O primeiro ocupa memória, deixando uma função global anônima? Onde o parêntese deve ser localizado?
javascript
syntax
anonymous-function
iife
Kevin Hakanson
fonte
fonte
Respostas:
Eles são virtualmente os mesmos.
O primeiro envolve parênteses em torno de uma função para torná-la uma expressão válida e a invoca. O resultado da expressão é indefinido.
O segundo executa a função e os parênteses em torno da invocação automática tornam-na uma expressão válida. Ele também é avaliado como indefinido.
Não acho que haja uma maneira "certa" de fazer isso, já que o resultado da expressão é o mesmo.
fonte
+function(){}()
ou!function(){}()
.-function(){}();
,!function(){}();
e basicamente qualquer outro operador imediatamente anteriorfunction
também funciona, mas preferiria as versões que usam parênteses). Vejo o primeiro muito mais do que vejo o segundo, e é minha preferência; faz mais sentido para mim também, mas isso é subjetivo. FWIW: jsbin.com/ejaqowNesse caso, não importa. Você está invocando uma expressão que resolve para uma função na primeira definição e definindo e invocando imediatamente uma função no segundo exemplo. Eles são semelhantes porque a expressão de função no primeiro exemplo é apenas a definição da função.
Existem outros casos mais obviamente úteis para invocar expressões que resolvem em funções:
fonte
foo = function(){alert('hi');}
se nenhuma das funções for uma função, será gerado um erro.foo
for "verdadeiro", mas não uma função.Não há nenhuma diferença além da sintaxe.
Em relação às suas preocupações sobre o segundo método de fazer isso:
Considerar:
(function namedfunc () { ... }())
namedfunc
ainda não estará no escopo global, embora você tenha fornecido o nome. O mesmo vale para funções anônimas. A única maneira de colocá-lo nesse escopo seria atribuí-lo a uma variável dentro dos parênteses.Os parênteses externos são desnecessários:
Mas você não queria essa declaração global de qualquer maneira, queria?
Então, tudo se resume a:
E você pode reduzir ainda mais: o nome é desnecessário, pois nunca será usado (a menos que sua função seja recursiva .. e mesmo assim você poderia usar
arguments.callee
)É assim que penso (pode estar incorreto, ainda não li a especificação ECMAScript). Espero que ajude.
fonte
arguments.callee
está obsoleto desde ES5 (e proibido no modo estrito).A diferença existe porque Douglas Crockford não gosta do primeiro estilo para IIFEs ! (sério) Como você pode ver neste vídeo !! .
A única razão para a existência do invólucro extra
()
{em ambos os estilos} é ajudar a fazer essa seção do código Expressão de Função , porque a Declaração de Função não pode ser chamada imediatamente. Alguns scripts / minify-ers uso apenas+
,!
,-
e~
em vez de também parênteses. Como isso:E tudo isso é exatamente igual às suas alternativas. A escolha entre esses casos é totalmente por sua conta e não faz diferença. {Aqueles que
()
produzem um arquivo maior de 1 byte ;-)}fonte