Maison  >  Article  >  interface Web  >  Explication détaillée de la déclaration des variables JavaScript et de la substitution de variables locales par des variables globales

Explication détaillée de la déclaration des variables JavaScript et de la substitution de variables locales par des variables globales

伊谢尔伦
伊谢尔伦original
2017-07-18 09:54:232343parcourir

Les éléments définis en dehors du corps de la fonction sont des variables globales, et ceux définis à l'intérieur du corps de la fonction sont des variables locales. La définition ici fait référence à la déclaration via var.

JavaScript a le concept de globales implicites, ce qui signifie que toute variable que vous ne déclarez pas deviendra une propriété d'objet globale. Par exemple :

function test(){
    myname = "huming";
    alert(myname);
}
test();  // "huming"
alert(myname);  //"huming"

Les deux résultats sont identiques, indiquant que monnom est une variable globale.

Alors, y a-t-il une différence entre les variables globales implicites et les variables globales explicitement définies ? . La réponse est définitivement oui, regardez l'exemple suivant :

// 定义三个全局变量
var global_test1 = 1;
global_test2 = 2; // 反面教材
(function () {
    global_test3 = 3; // 反面教材
}());
// 试图删除
delete global_test1; // false
delete global_test2; // true
delete global_test3; // true
// 测试该删除
alert(typeof global_test1); // "number"
alert(typeof global_test2); // "undefined"
alert(typeof global_test3); // "undefined"

Comme le montre l'exemple ci-dessus : global_test1 défini par var en dehors de la fonction ne peut pas être supprimé, tandis que global_test2 et global_test3 ne sont pas définis par var . sont supprimés (qu’ils soient créés ou non dans le corps de la fonction).

En résumé, les variables globales déclarées via var en dehors de la fonction ne peuvent pas être supprimées, mais les variables globales implicites peuvent être supprimées.

Il convient de noter ici : JavaScript a un comportement appelé "hoisting" (suspension/analyse supérieure/pré-analyse).

Illustrons avec un exemple :

var myname = "huming"; //声明全局变量
function test() {
    alert(myname);
    var myname = "local_huming";
    alert(myname);
}
test();

Pensez-vous que le contenu des deux alertes est cohérent ? ? Manifestement incohérent, il va sans dire cohérent. . La sortie réelle est : "undefined", "local_huming".

L'exemple ci-dessus est équivalent à

var myname = "huming"; //声明全局变量
function test() {
  var myname;
  alert(maname);<br>  myname = "local_huming";
  alert(myname);    // "local"
}
test();

Le myname généré par la première alerte n'est pas la variable globale que vous pensez, mais est dans la même portée (un corps de fonction) avec sa variable locale variables. Même s’il n’a pas été déclaré, il est traité comme tel. C'est ce qu'on appelle le « levage ».

Cela devrait être clair. Lorsque vous utilisez une variable dans le corps d’une fonction et que vous la déclarez à nouveau ultérieurement, une erreur peut se produire.

Spécifications d'écriture :

function test() {
   var a = 1,
       b = 2,
       c = a + b,
       d = {},
       e,
       f;
   // function body...
}

Les avantages sont :

1. Toutes les variables locales sont définies au début de la fonction, ce qui la rend facile à trouver ; >

2. Empêcher une erreur logique lorsqu'une variable est utilisée avant qu'elle ne soit définie.

Comment remplacer ?

Lorsqu'il s'agit d'améliorer les performances de JavaScript, le conseil le plus couramment entendu est d'utiliser des variables locales au lieu de variables globales. C'est un conseil qui m'est resté et qui ne l'a jamais remis en question au cours de mes neuf années de travail dans le développement Web, et il est basé sur la gestion de la méthode de cadrage et de résolution d'identifiant (résolution d'identifiant) par JavaScript.

Tout d'abord, nous devons préciser que les fonctions sont incarnées sous forme d'objets en JavaScript. Le processus de création d'une fonction est en fait le processus de création d'un objet. Chaque objet fonction possède une propriété interne appelée [[Scope]], qui contient les informations de portée lors de la création de la fonction. En fait, l'attribut [[Scope]] correspond à une liste d'objets (Variable Objects), et les objets de la liste sont accessibles depuis l'intérieur de la fonction. Par exemple, si nous créons une fonction globale A, alors la propriété interne [[Scope]] de A ne contient qu'un seul objet global (Global Object), et si nous créons une nouvelle fonction B dans A, alors l'attribut [[Scope] ] de B contient deux objets, l'objet Activation Object de la fonction A est à l'avant et l'objet global (Global Object) est à l'arrière.

Lorsqu'une fonction est exécutée, un objet exécutable (Execution Object) sera automatiquement créé et lié à une chaîne de portée (Scope Chain). La chaîne de portée sera établie à travers les deux étapes suivantes pour la résolution des identifiants.

Tout d'abord, copiez les objets dans les propriétés internes de l'objet fonction [[Scope]] dans la chaîne de portée dans l'ordre.

Deuxièmement, lorsque la fonction est exécutée, un nouvel objet objet d'activation sera créé. Cet objet contient les définitions de celui-ci, les paramètres (arguments) et les variables locales (y compris les paramètres nommés). Placé à l'avant de la chaîne de lunette.

Lors de l'exécution du code JavaScript, lorsqu'un identifiant est rencontré, il sera recherché dans la chaîne de portée du contexte d'exécution (Execution Context) en fonction du nom de l'identifiant. En commençant par le premier objet de la chaîne de portée (l'objet Objet d'activation de la fonction), s'il n'est pas trouvé, recherchez l'objet suivant dans la chaîne de portée, et ainsi de suite, jusqu'à ce que la définition de l'identifiant soit trouvée. Si le dernier objet de la portée, qui est l'objet global, n'est pas trouvé après la recherche, une erreur sera générée, indiquant à l'utilisateur que la variable n'est pas définie. Il s'agit du modèle d'exécution de fonction et du processus de résolution d'identifiant (Identifier Resolution) décrit dans la norme ECMA-262. Il s'avère que la plupart des moteurs JavaScript sont effectivement implémentés de cette manière. Il convient de noter que l'ECMA-262 n'impose pas l'utilisation de cette structure, mais décrit uniquement cette partie de la fonction.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

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