Les mots précédents
La plupart du temps, la principale raison pour laquelle nous sommes confus au sujet de la portée est que nous ne pouvons pas distinguer si les recherches variables doivent être effectuées dans l'ordre imbriqué des positions de fonction ou dans l'ordre des appels de fonction. Couplée à l'interférence de ce mécanisme, la recherche variable est très sujette aux erreurs. Ceci est en fait causé par deux modèles de travail de portée. La portée est divisée en portée lexicale et en portée dynamique. En distinguant ces deux modèles de portée, vous pouvez avoir une compréhension claire du processus de recherche variable. Cet article est le deuxième chapitre de la série JavaScript Scope - Scope lexicale et portée dynamique
Portée lexicale
Comme mentionné dans le premier article, la première étape de travail du compilateur est appelée Word participe, qui décompose une chaîne composée de caractères en unités lexicales. Ce concept est la base de la compréhension de la portée lexicale
Autrement dit, la portée lexicale définit la portée au stade lexical, qui est déterminée par où les variables et la portée du bloc sont écrites lors de l'écriture du code. Par conséquent, la portée reste inchangée lorsque l'analyseur lexical traite le code.
relation
Peu importe où la fonction est appelée, et peu importe comment elle est appelée, sa portée lexicale n'est déterminée que par la position où la fonction est déclarée.
fonction foo (a) {var b = a * 2; fonction bar (c) {console.log (a, b, c);} bar (b * 3);} foo (2); // 2 4 12Dans cet exemple, il existe trois portées imbriquées. Pour aider à comprendre, considérez-les comme plusieurs bulles qui sont incluses étape par étape
Les bulles de portée sont déterminées par où leur code de bloc de portée correspondant est écrit, et ils sont inclus étape par étape.
La bulle 1 contient toute la portée mondiale, avec un seul identifiant: FOO
La bulle 2 contient la portée créée par Foo, qui a trois identifiants: A, bar et b
La bulle 3 contient la portée créée par Bar, avec un seul identifiant: C
Trouver
La structure des bulles de portée et leurs relations positionnelles fournissent au moteur des informations de position suffisantes, que le moteur utilise pour trouver l'emplacement de l'identifiant.
Dans l'extrait de code, le moteur exécute la déclaration console.log (...) et recherche des références aux trois variables a, b et c. Il commence d'abord avec la portée la plus intérieure, c'est-à-dire la portée de la fonction Bar (...). Le moteur ne peut pas trouver ici, il passera donc au niveau précédent pour continuer à rechercher dans le cadre du FOO imbriqué (...). A se trouve ici, donc le moteur utilise cette référence. Il en va de même pour b. Et pour C, le moteur l'a trouvé en barre (...)
[Remarque] La recherche de portée lexicale ne recherchera que les identificateurs de premier niveau. Si le code fait référence à foo.bar.baz, la recherche de portée lexicale n'essaiera que de trouver des identificateurs FOO. Après avoir trouvé cette variable, les règles d'accès à l'attribut objet prennent respectivement l'accès aux attributs Bar et Baz
foo = {bar: {baz: 1}}; console.log (foo.bar.baz); // 1Couverture
La recherche de portée commence à partir de la portée la plus intérieure à laquelle se trouve l'exécution et se déroule étape par étape vers l'extérieur ou vers le haut jusqu'à ce que le premier identifiant correspondant soit rempli.
Les identifiants avec le même nom peuvent être définis dans des lunettes imbriquées multicouches, qui est appelée "effet d'occlusion". Les identificateurs internes "occlus" des identifiants externes
var a = 0; fonction test () {var a = 1; console.log (a); // 1} test ();Les variables globales sont automatiquement les attributs des objets globaux, de sorte qu'ils peuvent être accessibles directement par référence aux attributs des objets globaux au lieu de passer directement le nom lexical de l'objet global.
var a = 0; fonction test () {var a = 1; console.log (fenêtre.a); // 0} test ();Cette technique permet d'accéder à des variables globales masquées par des variables du même nom. Mais si les variables non globales sont bloquées, elles ne peuvent être accessibles quoi qu'il arrive.
Portée dynamique
JavaScript utilise la portée lexicale, et sa caractéristique la plus importante est que son processus de définition a lieu pendant la phase d'écriture du code.
Alors pourquoi introduire une portée dynamique? En fait, la portée dynamique est un autre mécanisme important de JavaScript pour le cousin. La plupart de la confusion de la portée est parce que la portée lexicale et ce mécanisme sont confus, donc je ne peux pas faire la différence entre stupidement
Les portées dynamiques ne se soucient pas de la façon dont les fonctions et les lunettes sont déclarées et déclarées n'importe où, uniquement d'où elles sont appelées. En d'autres termes, les chaînes de portée sont basées sur la pile d'appels, pas la nidification de la portée dans le code
var a = 2; fonction foo () {console.log (a);} fonction bar () {var a = 3; foo ();} bar ();[1] Si c'est dans la portée lexicale, c'est l'environnement JavaScript actuel. La variable a est d'abord recherchée dans la fonction foo (), mais elle n'est pas trouvée. Suivez donc la chaîne de portée pour rechercher dans la portée globale, trouver et attribuer une valeur de 2. Ainsi, la console sortira 2
【2】 S'il est dans la portée dynamique, de même, la variable a est d'abord recherchée dans foo () et non trouvée. Ici, vous suivrez la pile d'appels pour rechercher à l'endroit où la fonction foo () est appelée, c'est-à-dire la fonction bar (), trouver et affecter la valeur à 3. Ainsi, la console sortira 3
Résumé: La différence entre les deux portées. En bref, la portée lexicale est déterminée au moment de la définition, tandis que la portée dynamique est déterminée au moment de l'exécution.
Ce qui précède est la deuxième partie de la portée lexicale et de la portée dynamique qui vous est présentée par l'éditeur. J'espère que cela vous sera utile. Si vous voulez en savoir plus, veuillez faire attention à wulin.com!