Percebi uma diferença ao chamar uma função com parênteses vazios ou sem nenhum parêntese. No entanto, não estou passando nenhum argumento para a função, então me perguntei, qual seria a diferença entre:
window.onload = initAll();
e
window.onload = initAll;
Explique o princípio por trás disso.
javascript
reitor
fonte
fonte
(
PARÊNTESE ESQUERDO = parêntese de abertura (1.0) e 0029)
PARÊNTESE DIREITO = parêntese de fechamento (1.0) - unicode.org/charts/charindex.html#P e o que Dictionary.com tem a dizer sobre isso - dictionary.reference.com/ browse / PARENTHESIS "Uma ou ambas as linhas curvas verticais, () ..."{}
são chamados de colchetes de esquilo.Respostas:
Isso é executado
initAll()
imediatamente e atribui o valor de retorno da função awindow.onload
. Geralmente não é isso que você deseja.initAll()
teria que retornar uma função para que isso fizesse sentido.isso atribui a função real a
window.onload
- isso é possível porque em JavaScript, como diz @Felix, funções são objetos de primeira classe - sem executá-lo.initAll
será executado pelo evento de carregamento.fonte
O que Pekka disse está correto, mas eu quero elaborar um pouco com um exemplo que ajudará a explicar para alguém que não entende totalmente os ponteiros de função ou delegados.
Não vou usar
window.onload
porque é um pouco artificial para demonstrar. Usarei uma função simples de multiplicação para demonstrar:Isso também poderia ser escrito:
Enquanto no primeiro exemplo a implicação pode não ser óbvia, o segundo exemplo mostra mais claramente que estamos atribuindo uma função que tem 2 parâmetros para uma variável chamada
Multiply
, e este conceito de funções como atribuições é comum em todo o JavaScript. Esta é uma pequena demonstração do fato de que as funções são "cidadãos de primeira classe" , ou seja, podem ser repassadas exatamente como se estivéssemos passando valores.Agora, para a diferença de atribuição:
No ponto de definição da variável ret,
Multiply
é executado e o valor de retorno é atribuído -ret
torna - se igual a 12.Vamos tentar novamente de uma maneira diferente:
Agora, no ponto de definição
ret
,ret
torna-se suaMultiply
função em oposição a ser o resultado obtido de suaMultiply
função. Chamadas pararet()
farão com que suaMultiply
função seja executada, e você pode chamá-la exatamente como se tivesse chamadoMultiply(operator, operand)
:é o mesmo que
Você disse efetivamente que vai usar
ret
como delegado paraMultiply()
. Ao chamarret
, estamos realmente nos referindo àMultiply
função.De volta ao seu
window.onload
. Pense nisso como:Como você pode ver,
window.onload
é uma função como qualquer outra função, não há nada de especial nela. Você pode atribuir a ele um valor, atribuir uma função e anular se desejar - o ponto é que não há nada mais especial dowindow.onload
que sua própria função. A única coisa ligeiramente diferente é que ele é chamado pela janela quando é carregado. [Aviso de isenção: eu nunca realmente anulei as funções da janela, então não tenho certeza se isso causará repercussões negativas. Espera-se que eles verifiquem se uma função está atribuída antes de chamá-la, ieif (window.onload) window.onload();
].Agora chamar
initAll()
o que estamos dizendo é:que poderia muito bem dizer:
Mas quando dizemos
initAll
sem os parênteses, o que estamos realmente dizendo é: eu quero substituir qualquer que seja a minha função window.onload, por uma nova função - ou seja, eu quero substituí-la pela minhainitAll
função, para que qualquer chamada awindow.onload
execute meuinitAll
código.Assim:
é substituído por:
Portanto, qualquer chamada para
window.onload
executará suainitAll
função em vez do quewindow.onload
era originalmente. Você substituiu a função original pela nova função.Na verdade, você também pode escrever:
Outro exemplo que pode demonstrar melhor é este:
Qualquer que seja a hora na hora
d
definida, ela acaba sendo atribuídacurrentTime
. Ótimo, mas isso só é útil se quisermos saber a que horas a função que contém esse código foi chamada - ou seja, na hora de carregar a página. E se quisermos a hora atual a qualquer hora quecurrentTime
for chamada?Observe como chamamos
b()
nossas atribuiçõesc
ed
exatamente como poderíamos chamarcurrentTime()
?fonte
As funções em javascript são cidadãos de primeira classe e, como tal, podem ser atribuídas a outras variáveis ou passadas como argumentos.
Então, quando você faz
Você está definindo a
onload
propriedade dowindow
objeto para fazer referência àinitAll
própria função.Quando você faz
Você está definindo a
onload
propriedade para conter o valor de retorno de initAll, uma vez que ele será executado no lugar nessa linha.fonte
initAll
é uma referência a um valor de função e o operador colchetes anexado ao nome da função RUNS este objeto de função.Então, se você fizer algo como
então
a
se tornará o mesmoinitAll
- por exemplo, você pode fazera()
- mas coma variável
a
obterá o valor de retorno dainitAll
função executadafonte
Estou 6 anos atrasado, mas acho que isso poderia ter sido explicado de forma muito mais simples do que as respostas acima.
Então aqui está o TLDR ; ou vista aérea ao chamar funções usando e não usando
()
'sVamos pegar esta função, por exemplo:
se você logar "foo" - sem
()
Usando nenhum
()
meio para buscar a própria função . Você faria isso se quiser que seja repassado como um retorno de chamada.se você logar "foo ()" - com
()
Usar
()
depois de uma função significa executar a função e retornar seu valor .fonte