Question originale:
JSHint se plaint lorsque mon JavaScript appelle une fonction qui est définie plus bas dans la page que l'appel. Cependant, ma page est pour un jeu, et aucune fonction n'est appelée tant que tout n'a pas été téléchargé. Alors, pourquoi les fonctions de commande apparaissent-elles dans mon code?
EDIT: Je pense que j'ai peut-être trouvé la réponse.
http://www.orrectatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
Je gémis à l'intérieur. On dirait que j'ai besoin de passer UNE AUTRE journée à réorganiser six mille lignes de code. La courbe d'apprentissage avec javascript n'est pas du tout raide, mais elle est très longue.
javascript
function
jslint
jshint
Chris Tolworthy
la source
la source
Réponses:
tl; dr Si vous n'appelez rien tant que tout n'est pas chargé, ça devrait aller.
Edit: Pour un aperçu qui couvre également certaines déclarations ES6 (
let
,const
): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_CheatsheetCe comportement étrange dépend de
Voici quelques exemples.
C'est à cause de quelque chose qui s'appelle le levage !
Il existe deux façons de définir des fonctions: la déclaration de fonction et l' expression de fonction . La différence est ennuyeuse et infime, alors disons simplement cette chose légèrement fausse: si vous l'écrivez comme
function name() {}
, c'est une déclaration , et quand vous l'écrivez commevar name = function() {}
(ou une fonction anonyme affectée à un retour, des choses comme ça), c'est une expression de fonction .Voyons d'abord comment les variables sont gérées:
Maintenant, comment les déclarations de fonction sont gérées:
Les
var
instructions "jettent" la création defoo
tout en haut, mais ne lui attribuent pas encore de valeur. La déclaration de fonction vient ensuite sur la ligne, et finalement une valeur est affectée àfoo
.Et qu'en est-il de ça?
Seule la déclaration de
foo
est déplacée vers le haut. L'affectation intervient uniquement après l'appel àbar
, là où elle se trouvait avant que tout le levage ne se produise.Et enfin, par concision:
Maintenant, qu'en est-il des expressions de fonction ?
Tout comme les variables régulières, la première
foo
est déclarée au point le plus élevé de la portée, puis une valeur lui est attribuée.Voyons pourquoi le deuxième exemple génère une erreur.
Comme nous l'avons vu précédemment, seule la création de
foo
est hissée, l'affectation vient là où elle apparaissait dans le code «original» (non hissé). Quandbar
est appelé,foo
une valeur lui est attribuée avantfoo === undefined
. Maintenant, dans le corps de fonction debar
, c'est comme si vous faisiezundefined()
, ce qui génère une erreur.la source
La raison principale est probablement que JSLint n'effectue qu'un seul passage sur le fichier, il ne sait donc pas que vous allez définir une telle fonction.
Si vous avez utilisé la syntaxe des instructions de fonctions
Il n'y a en fait aucune différence là où vous déclarez la fonction (elle se comporte toujours comme si la déclaration était au début).
D'un autre côté, si votre fonction a été définie comme une variable régulière
Vous devez garantir que vous ne l'appellerez pas avant l'initialisation (cela peut en fait être une source de bogues).
Puisque réorganiser des tonnes de code est compliqué et peut être une source de bogues en soi, je vous suggère de rechercher une solution de contournement. Je suis presque sûr que vous pouvez dire à JSLint le nom des variables globales à l'avance afin qu'il ne se plaint pas de choses non déclarées.
Mettre un commentaire sur le début du fichier
Ou vous pouvez utiliser une zone de texte pour cela. (Je pense également que vous pouvez le transmettre dans les arguments à la fonction jslint interne si vous pouvez vous en mêler.)
la source
Il y a beaucoup trop de gens qui poussent des règles arbitraires sur la façon dont JavaScript doit être écrit. La plupart des règles sont des conneries.
Le levage de fonctions est une fonctionnalité de JavaScript car c'est une bonne idée.
Lorsque vous avez une fonction interne qui est souvent l'utilité des fonctions internes, l'ajouter au début de la fonction externe est un style acceptable d'écriture de code, mais cela présente l'inconvénient de devoir lire les détails pour arriver à quoi la fonction extérieure le fait.
Vous devez vous en tenir à un principe tout au long de votre base de code, soit mettre les fonctions privées en premier ou en dernier dans votre module ou fonction. JSHint est bon pour renforcer la cohérence, mais vous devez ABSOLUMENT ajuster le .jshintrc en fonction de vos besoins, PAS ajuster votre code source aux concepts de codage farfelus d'autres peuples.
Un style de codage que vous pourriez voir dans la nature, vous devriez éviter car il ne vous donne aucun avantage et seulement une douleur de refactoring possible:
C'est exactement ce que le levage de fonction est là pour éviter. Apprenez simplement la langue et exploitez ses atouts.
la source
Seule la déclaration de fonction est levée et non l'expression de fonction (affectation).
la source