Dans chaque langage de programmation, ses variables ont une certaine plage valide. Après avoir dépassé cette plage, les variables deviendront invalides. Ceci est la portée de la variable. D'un point de vue mathématique, c'est le domaine des variables indépendantes.
La portée est la gamme accessible de variables, c'est-à-dire que la portée contrôle le cycle de visibilité et de vie des variables et des fonctions. En JavaScript, les objets et les fonctions sont également des variables, et les variables sont définies à l'intérieur du corps de fonction arbitraire imbriqué par le corps de leur fonction et le corps de fonction arbitraire imbriqués.
1. Portée statique et portée dynamique
Portée statique
Cela signifie que la portée de la déclaration est déterminée au moment de la compilation en fonction de l'organisme du programme, également connu sous le nom de portée lexicale. La plupart des langages de programmation modernes adoptent des règles de portée statiques et JavaScript adopte cette portée.
Dans les langues qui utilisent des lunettes statiques, les règles de portée imbriquées les plus internes sont essentiellement: l'identifiant introduit par une déclaration est visible dans la portée où la déclaration est située, et également dans chaque portée imbriquée à l'intérieur, sauf si elle est couverte par une autre déclaration du même nom Identificateur imbriqué à l'intérieur.
Afin de trouver l'objet référencé par un identifiant donné, il doit être trouvé dans la portée la plus intérieure actuelle. Si une déclaration est trouvée, l'objet référencé par l'identifiant peut être trouvé. Sinon, nous rechercherons dans la portée extérieure directe et continuerons à vérifier la portée extérieure afin de l'extérieur jusqu'à ce que nous atteignions le niveau de nidification le plus extérieur du programme, c'est-à-dire la portée où se trouve la déclaration globale d'objet. Si aucune déclaration n'est trouvée à tous les niveaux, le programme a une erreur. comme suit:
fonction cha () {var name = "xiao;" fonction chb () {fonction chc () {console.log (name); }}}Tout d'abord, la fonction recherche la définition du nom de Chb (), puis continue de rechercher la couche par couche. Enfin, la définition du nom se trouve dans cha (). S'il n'est pas trouvé, une erreur sera signalée.
2. Portée dynamique
Dans une langue dynamiquement portée, l'objet référencé par une variable du programme est déterminé en fonction des informations de flux de contrôle du programme au moment de l'exécution du programme.
2. La portée de JavaScript
Il y a deux portées en JavaScript, à savoir la portée mondiale et la portée locale.
1. Portée mondiale
Il y a une définition n'importe où dans le code. Même si une variable globale est définie dans un morceau de code JS imbriqué dans la page HTML, la variable est toujours accessible dans le fichier JS référencé. Cela est très susceptible de provoquer la pollution aux variables mondiales.
Les variables dans les trois cas suivantes seront considérées comme des variables globales
(1) La fonction la plus externe et la variable la plus externe ont une portée globale
(2) les variables directement attribuées sans définition sont automatiquement déclarées avoir une portée globale
(3) Les propriétés de tous les objets de fenêtre ont une portée globale
2. Portée locale
Les portées locales ne sont généralement accessibles que dans des extraits de code fixes, tels que les variables à l'intérieur des fonctions (portée des fonctions)
var name = "xuxiaOping"; fonction eChoname () {var firstName = "xu"; // scope local SecondName = "xiao"; // Fonction d'étendue globale eChoFirstName () {console.log (prénom); // xu} console.log (seconde); return eChoFirstName;} console.log (name); // scope global var f = eChoname (); f (); console.log (firstName); console.log (deuxième nom);Le résultat est:
xuxiaoping
xiao
Xu // La fonction interne peut accéder aux variables de la fonction extérieure
Undenined // Les variables internes de la fonction ne sont pas accessibles en dehors de la fonction
xiao
JavaScript attache des variables globales aux objets de fenêtre et devient une propriété d'objets Window.
3. Portée de la fonction
Portée au niveau du bloc: Tout ensemble d'instructions en accolades appartient à un bloc, et toutes les variables définies dans ce domaine sont invisibles en dehors du bloc de code. La plupart des langues de classe C ont des lunettes de niveau bloc.
Cependant, une caractéristique importante de JavaScript est qu'elle n'a pas de portée au niveau du bloc.
fonction echoi () {for (var i = 0; i <10; i ++) {; // console.log (i); } if (true) {var str = "Bonjour"; } console.log (i); console.log (str);} echoi ();Le résultat de la sortie est:
10
Bonjour
On peut voir qu'en dehors de l'instruction FOR (ou si, pendant que), la variable que j'ai définie dans le bloc est toujours accessible. Autrement dit, JavaScript ne prend pas en charge les lunettes de niveau de bloc, il ne prend en charge que les lunettes de fonction et les variables définies n'importe où dans une fonction sont visibles n'importe où dans cette fonction. En tant que personne qui apprend C et Java depuis le début, c'est un peu difficile à adapter. Selon mes tests, il en va de même pour PHP.
Bien sûr, vous pouvez utiliser les caractéristiques de fermeture de JavaScript pour simuler la portée au niveau du bloc
fonction echoi () {(function () {for (var i = 0; i <10; i ++) {; // console.log (i);}}) (); if (true) {var str = "Bonjour"; } console.log (i); console.log (str);} echoi ();Le résultat est: je suis indéfini
Cela isole la définition des variables. Dans JS, afin d'éviter les conflits de dénomination, les variables globales et les fonctions globales doivent être évitées autant que possible, de sorte que ce type de fermeture est utilisé de plusieurs manières.
4. Cycle de vie variable JavaScript
Le cycle de vie de la variable JavaScript est initialisé lorsqu'il est déclaré.
Les variables locales sont détruites après l'exécution de la fonction.
Les variables globales sont détruites après la fermeture de la page.
3. Chaîne de portée JavaScript
Il ressemble à une chaîne, elle peut probablement être combinée avec la liste liée dans la structure des données.
Dans JavaScript, les fonctions sont des objets, mais en fait, tout dans JavaScript est des objets. Les objets de fonction, comme d'autres objets, ont des propriétés accessibles via le code et une série de propriétés internes qui ne sont accessibles qu'au moteur JavaScript. L'une des propriétés internes est [[Scope]], définie par la troisième édition de la norme ECMA-262. Ces propriétés internes contiennent une collection d'objets dans la portée créée par la fonction. Cette collection est appelée la chaîne de fonctions de portée, qui détermine les données accessibles par les fonctions.
Lorsqu'une fonction est créée, sa chaîne de portée est remplie d'objets de données accessibles dans la portée de la fonction. Par exemple, définissez une fonction comme celle-ci:
fonction add (num1, num2) {var sum = num1 + num2; Somme de retour;}Lorsque l'ajout de fonction est créé, un objet global sera rempli dans sa chaîne de portée, qui contient toutes les variables globales, comme indiqué sur la figure ci-dessous (Remarque: L'image ne donne que certaines de toutes les variables):
La portée de la fonction ADD sera utilisée pendant l'exécution. Par exemple, exécutez le code suivant:
var total = add (5,10);
Lors de l'exécution de cette fonction, un objet interne appelé "contexte d'exécution" est créé. Le contexte d'exécution définit l'environnement dans lequel la fonction est exécutée. Chaque contexte d'exécution a sa propre chaîne de portée pour l'analyse des identificateurs. Lorsque le contexte d'exécution est créé, sa chaîne de portée est initialisée en tant qu'objet contenu dans [[SPOCE]] de la fonction de course actuelle.
Ces valeurs sont copiées dans la chaîne de portée du contexte d'exécution dans l'ordre dans lequel elles apparaissent dans la fonction. Ensemble, ils forment un nouvel objet appelé "Objet d'activation", qui contient toutes les variables locales, des paramètres nommés, des ensembles de paramètres et cette fonction. Ensuite, cet objet sera poussé à l'avant de la chaîne de portée. Lorsque le contexte de course est détruit, l'objet actif sera détruit. La nouvelle chaîne de portée est représentée dans la figure ci-dessous:
Pendant l'exécution de la fonction, chaque fois qu'une variable est rencontrée, un processus d'analyse d'identifiant sera transmis pour décider où obtenir et stocker des données. Ce processus part à partir de la tête de la chaîne de portée, c'est-à-dire rechercher un identifiant du même nom de l'objet actif. S'il est trouvé, utilisez la variable correspondant à cet identifiant. S'il n'est pas trouvé, continuez à rechercher l'objet suivant dans la chaîne de portée. Si tous les objets ne sont pas trouvés après la recherche, l'identifiant est considéré comme non défini. Pendant l'exécution de la fonction, chaque identifiant doit passer par un tel processus de recherche.
4. Chaîne de portée et optimisation du code
D'après la structure de la chaîne de portée, on peut voir que dans la chaîne de portée du contexte d'exécution, plus l'identificateur est profond, plus la vitesse de lecture et d'écriture sera lente. Comme le montre la figure ci-dessus, car les variables globales existent toujours à la fin de la chaîne de portée de contexte pendant l'exécution, il est le plus lent de trouver des variables globales lors de l'analyse de l'identifiant. Par conséquent, lors de l'écriture de code, vous devez essayer d'utiliser le moins de variables globales le moins possible et utiliser autant que possible les variables locales. Une bonne règle de base est: si un objet croisé est référencé plus d'une fois, stockez-le dans une variable locale avant utilisation. Par exemple, le code suivant:
function changecolor () {document.getElementById ("btnchange"). onClick = function () {document.getElementById ("TargetCanvas"). style.backgroundColor = "Red"; };}Cette fonction se réfère deux fois au document variable global. La variable doit être recherchée dans toute la chaîne de portée jusqu'à ce qu'elle soit enfin trouvée dans l'objet global. Ce code peut être réécrit comme suit:
function changEcolor () {var doc = document; doc.getElementById ("btnchange"). onClick = function () {doc.getElementById ("TargetCanvas"). style.backgroundColor = "Red"; };}Ce code est relativement simple et ne montrera pas une énorme amélioration des performances après la réécriture, mais si un grand nombre de variables globales du programme sont accessibles à plusieurs reprises, les performances du code après réécriture seront considérablement améliorées.
5. Avec la chaîne de portée du changement
Le contexte d'exécution correspondant est unique à chaque fois que le nombre est exécuté, donc appeler la même fonction plusieurs fois conduira à la création de plusieurs contextes d'exécution. Lorsque la fonction est exécutée, le contexte d'exécution sera détruit. Chaque contexte d'exécution est associé à une chaîne de portée. D'une manière générale, pendant le contexte de course, sa chaîne de portée ne sera affectée que par la déclaration avec la déclaration et l'instruction Catch.
L'instruction avec un moyen rapide d'appliquer des objets pour éviter d'écrire du code en double. Par exemple:
fonction initUi () {avec (document) {var bd = body, links = getElementsByTagName ("a"), i = 0, len = links.length; while (i <len) {update (liens [i ++]); } getElementById ("btNinit"). onClick = function () {DoSomething (); }; }}Utilisez des instructions de largeur ici pour éviter d'écrire le document plusieurs fois, ce qui semble plus efficace, mais crée en fait des problèmes de performances.
Lorsque le code s'exécute vers l'instruction avec, la chaîne de portée du contexte d'exécution est temporairement modifiée. Un nouvel objet mutable est créé, qui contient toutes les propriétés de l'objet spécifié par le paramètre. Cet objet sera poussé dans la tête de la chaîne de portée, ce qui signifie que toutes les variables locales de la fonction sont désormais dans le deuxième objet de chaîne de portée, donc l'accès est plus cher. Comme indiqué dans la figure ci-dessous:
Par conséquent, avec des déclarations doit être évité dans les programmes. Dans cet exemple, le simple fait de stocker le document dans une variable locale peut améliorer les performances.
Résumer
1. La portée d'une variable est où la portée de la variable est valide.
2. La chaîne de portée des variables est la collection d'objets dans la portée créés.
Ce qui précède concerne cet article, j'espère qu'il sera utile pour tout le monde d'apprendre la programmation JavaScript.