Esse código sempre funciona, mesmo em diferentes navegadores:
function fooCheck() {
alert(internalFoo()); // We are using internalFoo() here...
return internalFoo(); // And here, even though it has not been defined...
function internalFoo() { return true; } //...until here!
}
fooCheck();
Não consegui encontrar uma única referência para o porquê de funcionar. Vi isso pela primeira vez na nota de apresentação de John Resig, mas foi mencionada apenas. Não há explicação lá ou em qualquer lugar para esse assunto.
Alguém poderia, por favor, esclarecer-me?
javascript
function
Edu Felipe
fonte
fonte
Respostas:
A
function
declaração é mágica e faz com que seu identificador seja vinculado antes que qualquer coisa em seu bloco de código * seja executada.Isso difere de uma atribuição com uma
function
expressão, que é avaliada na ordem normal de cima para baixo.Se você alterou o exemplo para dizer:
Pararia de funcionar.
A declaração da função é sintaticamente bastante separada da expressão da função, mesmo que pareça quase idêntica e possa ser ambígua em alguns casos.
Isso está documentado no padrão ECMAScript , seção 10.1.3 . Infelizmente, o ECMA-262 não é um documento muito legível, mesmo para os padrões!
*: a função, bloco, módulo ou script que contém.
fonte
É chamado HOISTING - Invocando (chamando) uma função antes de ser definida.
Dois tipos diferentes de funções sobre os quais quero escrever são:
Funções de expressão e funções de declaração
Funções de expressão:
As expressões de função podem ser armazenadas em uma variável para que eles não precisem de nomes de função. Eles também serão nomeados como uma função anônima (uma função sem nome).
Para invocar (chamar) essas funções, elas sempre precisam de um nome de variável . Esse tipo de função não funcionará se for chamado antes de ser definido, o que significa que o Hoisting não está acontecendo aqui. Sempre devemos definir a função de expressão primeiro e depois invocá-la.
É assim que você pode escrevê-lo no ECMAScript 6:
Funções da declaração:
As funções declaradas com a seguinte sintaxe não são executadas imediatamente. Eles são "salvos para uso posterior" e serão executados mais tarde, quando forem chamados (chamados). Este tipo de função funciona se você chamá-lo ANTES ou DEPOIS de onde foi definido. Se você chamar uma função de declaração antes de ser definida, o Hoisting funcionará corretamente.
Exemplo de elevação:
fonte
let fun = theFunction; fun(); function theFunction() {}
também funcionará (nó e navegadores) #O navegador lê o seu HTML do começo ao fim e pode executá-lo à medida que é lido e analisado em partes executáveis (declarações de variáveis, definições de funções etc.).
Isso é diferente de outros contextos de programação que processam (compilam) todo o seu código-fonte, talvez o vincule a todas as bibliotecas necessárias para resolver as referências e construa um módulo executável, no qual a execução começa.
Seu código pode se referir a objetos nomeados (variáveis, outras funções etc.) definidos mais adiante, mas você não pode executar o código de referência até que todas as peças estejam disponíveis.
Ao se familiarizar com o JavaScript, você ficará intimamente ciente de sua necessidade de escrever as coisas na sequência correta.
Revisão: Para confirmar a resposta aceita (acima), use o Firebug para avançar pela seção de script de uma página da web. Você o verá pular de uma função para outra, visitando apenas a primeira linha, antes de realmente executar qualquer código.
fonte
Alguns idiomas exigem que os identificadores sejam definidos antes do uso. Uma razão para isso é que o compilador usa uma única passagem no código-fonte.
Mas se houver vários passes (ou alguns cheques forem adiados), você poderá viver perfeitamente sem esse requisito. Nesse caso, o código provavelmente é primeiro lido (e interpretado) e, em seguida, os links são definidos.
fonte
Eu apenas usei JavaScript um pouco. Não tenho certeza se isso ajudará, mas é muito parecido com o que você está falando e pode fornecer algumas dicas:
http://www.dustindiaz.com/javascript-function-declaration-ambiguity/
fonte
O corpo da função "internalFoo" precisa ir para algum lugar no momento da análise; portanto, quando o código é lido (também conhecido como análise) pelo interpretador JS, a estrutura de dados da função é criada e o nome é atribuído.
Somente mais tarde, o código é executado, o JavaScript realmente tenta descobrir se "internalFoo" existe e como é e se pode ser chamado etc.
fonte
Pelo mesmo motivo, o seguinte sempre será colocado
foo
no espaço para nome global:fonte
if
bloco não cria um escopo, enquanto umfunction()
bloco sempre cria um. O verdadeiro motivo foi que a definição de nomes globais de javascript ocorre na fase de compilação, para que, mesmo que o código não seja executado, o nome seja definido. (Desculpe demorou tanto tempo para comentário)