Maison  >  Article  >  interface Web  >  Suivez-moi pour apprendre les compétences de pré-analyse javascript var et de déclaration de fonction enhancement_javascript

Suivez-moi pour apprendre les compétences de pré-analyse javascript var et de déclaration de fonction enhancement_javascript

WBOY
WBOYoriginal
2016-05-16 15:32:091086parcourir

1. pré-compilation des variables var

La syntaxe de JavaScript est similaire à C, Java et C#, collectivement appelés syntaxe de type C. Les étudiants ayant de l'expérience en programmation C ou Java doivent connaître la règle « déclarer d'abord, utiliser plus tard ». Si vous utilisez des variables ou des fonctions non déclarées, une erreur sera signalée lors de la phase de compilation. Cependant, JavaScript peut utiliser des variables et des fonctions avant qu'elles ne soient déclarées. Examinons de plus près le mystère ci-dessous.

Regardons d'abord un morceau de code :

(function() {
 console.log(noSuchVariable);//ReferenceError: noSuchVariable is not defined
})();

Exécutez le code ci-dessus et une erreur sera signalée immédiatement. Cependant, c'est exactement ce à quoi nous nous attendions, car la variable noSuchVariable n'a pas du tout été définie ! Jetons un coup d'œil au code suivant :

(function() {
 console.log(declaredLater); //undefined
 var declaredLater = "Now it's defined!";
 console.log(declaredLater);// "Now it's defined!"
})();

Tout d’abord, le code ci-dessus est correct et il n’y a aucun problème. Mais pourquoi ne signale-t-il pas d’erreur ? La variable déclaréeLater est définie après l'instruction appelante ? Pourquoi la sortie n'est-elle pas définie ?

Cela est en fait dû à l'analyseur JavaScript. L'analyseur place toutes les variables et fonctions déclarées dans la portée actuelle au début de la portée. Cependant, seule la déclaration des variables est avancée au début de la portée. sont laissés en place. Le code ci-dessus ressemble en fait à ceci pour l'analyseur :

(function() {
 var declaredLater; //声明被提前到作用域开始处了!
 console.log(declaredLater); // undefined
 declaredLater = "Now it's defined!"; //赋值操作还在原地!
 console.log(declaredLater);//"Now it's defined!"
})();

C'est pourquoi le code ci-dessus ne signale pas d'exception ! Une fois les variables et les fonctions "avancées", la variable déclaréeLater est en fait placée devant la fonction appelante. Selon la définition de la syntaxe JavaScript, les variables qui ont été déclarées mais non affectées seront automatiquement affectées à undefined. La valeur de la variable déclaréeLater n'est pas définie. Plus tard, nous avons attribué une valeur à la variable déclaréeLater, donc lorsque nous imprimons la variable pour la deuxième fois, elle est maintenant définie !

Regardons un autre exemple :

var name = "Baggins";
(function () {
 console.log("Original name was " + name);// "Original name was undefined"
 var name = "Underhill";
 console.log("New name is " + name);// "New name is Underhill"
})();

Dans le code ci-dessus, nous déclarons d'abord un nom de variable. Notre intention initiale est de générer la variable de nom définie dans la portée globale lors de la première impression de la variable de nom, puis de définir une variable de nom locale dans la fonction pour couvrir les variables globales et enfin afficher la valeur de la variable locale. Cependant, le premier résultat est totalement incohérent avec nos attentes. La raison en est que les variables locales que nous avons définies sont « avancées » dans leur portée, c'est-à-dire qu'elles prennent la forme suivante :

var name = "Baggins";
(function () {
 var name; //注意:name 变量被提前了!
 console.log("Original name was " + name);// "Original name was undefined"
 name = "Underhill";
 console.log("New name is " + name);//"New name is Underhill"
})();

Étant donné que JavaScript a de telles « bizarreries », il est recommandé de placer la déclaration de variable en haut de la portée, afin que vous puissiez toujours vous rappeler d'y prêter attention.

2. La déclaration de fonction est "avancée"

Ce dont j'ai parlé plus tôt, ce sont les variables, parlons ensuite des fonctions.

Il existe deux situations dans lesquelles une fonction est "avancée", l'une est une déclaration de fonction et la seconde est une fonction assignée à une variable en tant que valeur, c'est-à-dire une expression de fonction.

Parlons d'abord de la première situation, le code :

isItHoisted();//"Yes!"
function isItHoisted() { 
 console.log("Yes!");
}

Comme indiqué ci-dessus, l'interpréteur JavaScript vous permet de l'utiliser avant la déclaration de fonction. En d'autres termes, la déclaration de fonction n'est pas seulement le nom de la fonction qui est « avancée », mais la définition entière de la fonction est également « avancée » ! Le code ci-dessus peut donc être exécuté correctement.

Regardons le deuxième cas : la forme d'expression de fonction. Commençons par le code :

definitionHoisted();// "Definition hoisted!"
definitionNotHoisted();// TypeError: undefined is not a function
function definitionHoisted() { 
 console.log("Definition hoisted!");
}
var definitionNotHoisted = function () { 
 console.log("Definition not hoisted!");
};

Nous avons fait une comparaison. La fonction definitionHoisted a été correctement exécutée, conforme au premier type ; la variable definitionNotHoisted était "avancée", mais son affectation (c'est-à-dire la fonction) n'était pas avancée de ce point de vue. pour dire, cela est tout à fait cohérent avec "l'avancement" des variables dont nous avons parlé plus tôt, et comme la valeur par défaut de la variable "avancement" n'est pas définie, l'erreur signalée appartient à "l'incompatibilité de type", car undéfini n'est pas une fonction, bien sûr, on ne peut pas l'appeler.

Résumé
Grâce à l'explication ci-dessus, cela peut se résumer ainsi :

La déclaration des variables est avancée en haut du scope, et l'affectation reste en place
La déclaration de fonction entière est "avancée"
Lors de l'utilisation d'une expression de fonction, seule la variable est "avancée", la fonction n'est pas "avancée"
3. Effets secondaires du var

Une petite différence entre les variables globales implicites et les variables globales explicitement définies est la possibilité de laisser les variables non définies via l'opérateur de suppression.

Les variables globales créées via var (créées dans n'importe quel programme en dehors des fonctions) ne peuvent pas être supprimées.
Les variables globales implicites créées sans var (qu'elles soient créées ou non dans une fonction) peuvent être supprimées.
Cela montre que, techniquement, les variables globales implicites ne sont pas vraiment des variables globales, mais ce sont des propriétés de l'objet global. Les attributs peuvent être supprimés via l'opérateur delete, mais les variables ne le peuvent pas :

// 定义三个全局变量
var global_var = 1;
global_novar = 2;  // 反面教材
(function () {
 global_fromfunc = 3; // 反面教材
}());

// 试图删除
delete global_var;  // false
delete global_novar; // true
delete global_fromfunc; // true

// 测试该删除
typeof global_var;  // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"

在ES5严格模式下,未声明的变量(如在前面的代码片段中的两个反面教材)工作时会抛出一个错误。

4、单var形式声明变量

在函数顶部使用单var语句是比较有用的一种形式,其好处在于:

提供了一个单一的地方去寻找功能所需要的所有局部变量
防止变量在定义之前使用的逻辑错误
少代码(类型啊传值啊单线完成)
单var形式长得就像下面这个样子:

function func() {
 var a = 1,
  b = 2,
  sum = a + b,
  myobject = {},
  i,
  j;
 // function body...
}

您可以使用一个var语句声明多个变量,并以逗号分隔。像这种初始化变量同时初始化值的做法是很好的。这样子可以防止逻辑错误(所有未初始化但声明的变量的初始值是undefined)和增加代码的可读性。在你看到代码后,你可以根据初始化的值知道这些变量大致的用途。

以上就是针对javascript的var预解析与函数声明提升的学习内容,希望对大家的学习有所帮助。

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn