Questão original:
JSHint reclama quando meu JavaScript chama uma função que é definida mais abaixo na página do que a chamada para ela. No entanto, minha página é para um jogo e nenhuma função é chamada até que tudo seja baixado. Então, por que as funções de pedido aparecem em meu código?
EDIT: Acho que posso ter encontrado a resposta.
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
Estou gemendo por dentro. Parece que preciso passar OUTRO dia reordenando seis mil linhas de código. A curva de aprendizado com javascript não é íngreme, mas é muuuuuito.
javascript
function
jslint
jshint
Chris Tolworthy
fonte
fonte
Respostas:
tl; dr Se você não estiver ligando para nada até que tudo carregue, você deve ficar bem.
Editar: para uma visão geral que também cobre algumas declarações ES6 (
let
,const
): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_CheatsheetEste comportamento estranho depende de
Aqui estão alguns exemplos.
Isso ocorre por causa de algo chamado içamento !
Existem duas maneiras de definir funções: declaração de função e expressão de função . A diferença é irritante e minuciosa, então vamos apenas dizer uma coisa um pouco errada: se você está escrevendo como
function name() {}
, é uma declaração , e quando você escreve comovar name = function() {}
(ou uma função anônima atribuída a um retorno, coisas assim), é uma expressão de função .Primeiro, vamos ver como as variáveis são tratadas:
Agora, como as declarações de função são tratadas:
As
var
declarações "jogam" a criação defoo
para o topo, mas ainda não atribuem o valor a ela. A declaração da função vem a seguir na linha e, finalmente, um valor é atribuídofoo
.E quanto a isso?
Apenas a declaração de
foo
é movida para o topo. A atribuição vem somente após a chamada parabar
ser feita, onde estava antes de ocorrer todo o içamento.E, finalmente, para concisão:
Agora, e quanto às expressões de função ?
Assim como as variáveis regulares, primeiro
foo
é declarado no ponto mais alto do escopo e, em seguida, é atribuído um valor.Vamos ver por que o segundo exemplo gera um erro.
Como vimos antes, apenas a criação de
foo
é içada, a atribuição vem onde apareceu no código "original" (não içada). Quandobar
é chamado, é antes defoo
ser atribuído um valor, entãofoo === undefined
. Agora, no corpo da função debar
, é como se você estivesse fazendoundefined()
, o que gera um erro.fonte
A principal razão é provavelmente que JSLint faz apenas uma passagem sobre o arquivo para que ele não sabe que você irá definir tal função.
Se você usou sintaxe de instrução de funções
Na verdade, não há nenhuma diferença onde você declara a função (ela sempre se comporta como se a declaração estivesse no início).
Por outro lado, se sua função foi definida como uma variável regular
Você tem que garantir que não vai chamá-lo antes da inicialização (isso pode realmente ser uma fonte de bugs).
Como reordenar toneladas de código é complicado e pode ser uma fonte de bugs, eu sugiro que você procure uma solução alternativa. Tenho certeza de que você pode informar ao JSLint o nome das variáveis globais de antemão, para que ele não reclame sobre coisas não declaradas.
Coloque um comentário no início do arquivo
Ou você pode usar uma caixa de texto para isso. (Eu também acho que você pode passar isso nos argumentos para a função jslint interna, se puder interferir nisso.)
fonte
Existem muitas pessoas empurrando regras arbitrárias sobre como o JavaScript deve ser escrito. A maioria das regras é um lixo absoluto.
A elevação de função é um recurso em JavaScript porque é uma boa ideia.
Quando você tem uma função interna que muitas vezes é a utilidade de funções internas, adicioná-la ao início da função externa é um estilo aceitável de escrever código, mas tem a desvantagem de ter que ler os detalhes para saber o que a função externa sim.
Você deve seguir um princípio em toda a sua base de código ou colocar as funções privadas primeiro ou por último em seu módulo ou função. JSHint é bom para garantir consistência, mas você deve ajustar ABSOLUTAMENTE o .jshintrc para atender às suas necessidades, NÃO ajustar seu código-fonte aos conceitos de codificação malucos de outras pessoas.
Um estilo de codificação que você pode ver à solta e que deve ser evitado porque ele não oferece vantagens e apenas a dor de refatoração possível:
Isso é exatamente o que o içamento de função deve ser evitado. Apenas aprenda a língua e explore seus pontos fortes.
fonte
Apenas a declaração de função é içada, não a expressão de função (atribuição).
fonte