Sintaxe de invocação de função imediata


110

Há uma opção JSLint , uma das boas partes na verdade, que "[requer] parênteses em torno de invocações imediatas", o que significa que a construção

(function () {

  // ...

})();

em vez disso, precisaria ser escrito como

(function () {

  // ...

}());

Minha pergunta é a seguinte - alguém pode explicar por que essa segunda forma pode ser considerada melhor? É mais resiliente? Menos sujeito a erros? Qual a vantagem disso sobre a primeira forma?


Depois de fazer essa pergunta, passei a compreender a importância de se ter uma distinção visual clara entre os valores das funções e os valores das funções. Considere o caso em que o resultado da invocação imediata é o lado direito de uma expressão de atribuição:

var someVar = (function () {

  // ...

}());

Embora os parênteses mais externos sejam sintaticamente desnecessários, o parêntese de abertura fornece uma indicação inicial de que o valor atribuído não é a própria função, mas sim o resultado da função que está sendo chamada.

Isso é semelhante ao conselho de Crockford sobre a capitalização das funções do construtor - serve como uma dica visual para qualquer pessoa que esteja olhando o código-fonte.


Obrigado por apontar isso. Nunca encontrei uma maneira de me livrar da mensagem de aviso do JSLint "Tenha cuidado ao criar funções dentro de um loop." Fui cuidadoso e coloquei a função em um encerramento, mas o JSLint ainda reclamou. Agora eu sei que assumiu que usei o segundo padrão.
viam0Zah


Eu tenho feito isso "errado" todo esse tempo. E quando digo "todo esse tempo", escrevo JavaScript desde 1995.
Dave Land

Respostas:


73

Do guia de convenção de estilo de Douglass Crockford : (pesquise "invocado imediatamente")

Quando uma função deve ser invocada imediatamente, toda a expressão de invocação deve ser agrupada em parênteses para que fique claro que o valor que está sendo produzido é o resultado da função e não a própria função.

Então, basicamente, ele sente que torna mais clara a distinção entre os valores das funções e os valores das funções. Portanto, é uma questão estilística, não é realmente uma diferença substantiva no código em si.

referência atualizada, o PPT antigo não existe mais


1
Estou feliz por ter lido isso. Acabei de ler Javascript: as partes boas, e fiquei pensando que atribuir o resultado da chamada de uma função é uma sintaxe muito ruim, porque você precisa olhar a primeira e a última linhas para entender o que está acontecendo. Ele não usa os parênteses de embrulho no livro, mas vejo exatamente por que os recomenda.
Skilldrick

2
@altCognito, você pode fornecer um novo link para o PPT?
th1rdey3


1
Não consegui encontrar o PPT original, mas consegui encontrar o mesmo ponto encontrado em seu guia de convenção javascript.
cgp

archive.org tem?
John Greene

2

Funções anônimas imediatamente chamadas são agrupadas em parênteses porque:

  1. Elas são expressões de função e deixar os parênteses de fora faria com que fossem interpretadas como uma declaração de função, o que é um erro de sintaxe.

  2. Expressões de função não podem começar com a palavra função.

  3. Ao atribuir a expressão de função a uma variável, a função em si não é retornada, o valor de retorno da função é retornado, portanto, os parênteses avaliam o que está dentro deles e produzem um valor.quando a função é executada e os parênteses posteriores ..}()fazem com que a função seja executada imediatamente.


Dathan, você está respondendo a uma pergunta diferente. Você está correto ao dizer que os parênteses às vezes são sintaticamente necessários para que o analisador possa distinguir expressões de função de declarações de função. Mas minha pergunta é sobre a colocação dos parênteses de invocação. Seu terceiro ponto é impreciso; os parênteses são desnecessários nesse caso.
Bobby Eickhoff

Eu estava respondendo ao seu primeiro exemplo em que a função imediatamente chamada anônima não foi atribuída a uma variável e, portanto, os parênteses são sintaticamente necessários pelos 2 primeiros motivos. A terceira razão foi apenas restabelecer o que você disse: "o parêntese de abertura dá uma indicação inicial de que o valor sendo atribuído não é a função em si, mas sim o resultado da função que está sendo chamada." Mas acho que não ficou claro.
Dathan

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.