Maison >interface Web >js tutoriel >Clarifier les portées lexicales, statiques, dynamiques, des fonctions et des blocs dans JS

Clarifier les portées lexicales, statiques, dynamiques, des fonctions et des blocs dans JS

黄舟
黄舟original
2017-02-28 15:00:121748parcourir

Eh bien, j'ai juste écrit beaucoup, mais cela a été écrasé par mon erreur╥﹏╥…

C'est bien de l'écrire à nouveau, je vous rappelle également de bloguer à ce sujet. et soyez comme moi. Pour les étudiants qui aiment aussi utiliser le langage markdown pour coder des mots
"Enregistrer en ligne pour brouillon" est une bonne habitude, hmm
Aujourd'hui, c'est Double Eleven, j'ai l'impression qu'il est temps d'acheter quelque chose. .


Lorsque de nombreux étudiants apprennent JavaScript, ils peuvent entendre parler de "diverses" portées
Que sont la portée lexicale, la portée statique, la portée dynamique, la portée de fonction, la portée de bloc
Je ne peux pas faites la différence
Permettez-moi de clarifier mes pensées pour tout le monde

Mode portée

Le mode de fonctionnement de la portée est divisé en deux types, le domaine de fonction statique et la portée dynamique
La portée statique comprend Portée de la fonction et portée du bloc
Les étudiants peuvent se demander qu'en est-il de la portée lexicale
En fait, la portée lexicale et la portée statique sont la même chose

Clarifier les portées lexicales, statiques, dynamiques, des fonctions et des blocs dans JS

L'image n'est pas bonne , tout le monde comprend ce que je veux dire.
Maintenant que nous avons clarifié ce point, entrons dans les détails

Je dois ajouter une question supplémentaire, à savoir : existe-t-il une portée dynamique en JavaScript ?
Sur ce point, j'ai obtenu des réponses complètement opposées dans deux livres que j'ai lus

Que ce soit l'instruction with ou la clause catch de l'instruction try-catch, ou qu'elle contienne L'eval( ) les fonctions sont toutes considérées comme des étendues dynamiques. La portée dynamique n'existe que pendant l'exécution du code et ne peut donc pas être détectée par une analyse statique (en examinant la structure du code). ——"JavaScript haute performance" /p24

Ce qui doit être clair, c'est qu'en fait JavaScript n'a pas de portée dynamique. Il n’a qu’une portée lexicale, claire et simple. Mais ce mécanisme s’apparente un peu à la portée dynamique. ——"JavaScript You Don't Know (Volume 1)" /p59

Ces deux livres sont très nouveaux, et tous deux font très autorité, fortement recommandés
en particulier "JavaScript You "Je ne sais pas", lorsque le deuxième tome est sorti le mois dernier, j'avais hâte d'en acheter un sur Internet
Je n'ai pas été déçu
Ahem, je me suis égaré, revenons au sujet
Je pense que les grands auteurs du livre original ont des compréhensions différentes de la portée dynamique
C'est pourquoi ce point de vue apparemment contradictoire
Ici, je veux parler de ma position
D'après ce que je comprends, je pense aussi Il n'y a pas de portée dynamique en JavaScript
Quelle est la différence entre la portée statique et dynamique
Regardez ci-dessous↓

Portée lexicale et portée dynamique

Permettez-moi de commencer par un morceau de code

function foo(){
    var a = 1;
    bar();
}function bar(){
    console.log(a);
}var a = 100;
foo();

Grâce à notre compréhension approfondie de la précompilation et de la portée
Dans la portée lexicale de notre JavaScript, le résultat final imprime 100

Mais si notre portée est un portée dynamique, ce qui est imprimé devient 1
Pourquoi ?
La caractéristique la plus importante de la portée lexicale est que son processus de définition se produit pendant la phase d'écriture (si eval() et with ne sont pas utilisés)
La portée dynamique permet de déterminer dynamiquement la portée au moment de l'exécution

La portée lexicale se soucie de l'endroit où la fonction est déclarée et la chaîne de portée est basée sur l'imbrication des portées
La portée dynamique se soucie de l'endroit où la fonction est appelée et la chaîne de portée est basée sur la pile d'appels

I traduit les mots ci-dessus en Le code est
Portée lexicale : parce que la fonction bar est déclarée globalement, donc j'affiche la valeur de la variable globale a
Portée dynamique : parce que la fonction bar est appelée dans la fonction foo, donc Je produis foo La valeur de la variable a dans
C'est ce que je comprends

Les langages de programmation avec lesquels je suis entré en contact maintenant sont limités et tous ont une portée lexicale, je n'en ai jamais vu. langage basé sur une portée dynamique
C, C, C#, Java, JavaScript et php sont tous des portées lexicales
Parmi eux, JavaScript et php sont basés sur la portée de la fonction, et les autres sont basés sur la portée du bloc

Portée de la fonction et portée du bloc

À ma connaissance
La portée de la fonction est la portée générée par le bloc de code de fonction, et la portée du bloc est la portée générée par le bloc de code entre accolades
J'ai vu cela écrit dans de nombreux blogs. En JavaScript, il n'y a que la portée de la fonction (grosse erreur)
C'est complètement incorrect et il n'y a pas de contestation
JavaScript est bien basé sur la portée de la fonction, mais cela ne veut pas dire que nous n'avons pas de portée de bloc
Il existe de nombreux cas particuliers. Il y a le mot-clé with, la clause catch de l'instruction try-catch, le mot-clé let (ES6) et le mot-clé const (ES6)
Ici, je j'en parlerai brièvement
Le mot-clé with et la clause catch peuvent tous deux être générés. Portée du bloc
J'en ai parlé en détail dans un article
Beaucoup d'entre vous qui sont intéressés peuvent y jeter un œil
Portail -> Évaluation lexicale de triche JavaScript, avec et catch et ses problèmes de performances

Le mot-clé let est très similaire à var, les deux déclarent des variables, mais le mot-clé let peut lier la variable à n'importe quelle portée dans laquelle elle se trouve
Et utiliser let pour déclarer ne sera pas promu dans la portée du bloc
Le Le mot-clé const déclare également des variables, mais il déclare des constantes et lie également les variables à la portée du bloc
C'est exactement la même chose que notre mot-clé const en C/C
Plus sur moi, j'en parlerai en détail quand je écrivez sur les connaissances ES6 plus tard
Maintenant, nous n'avons plus qu'à savoir « Il y a une portée de bloc en JavaScript »

Résumé

Comme d'habitude, je vais vous donner un résumé

  • Modes de fonctionnement de la portée : Portée lexicale/statique, portée dynamique

  • Portée lexicale : Portée de la fonction, portée du bloc

  • JavaScript n'a pas de portée dynamique

  • JavaScript a une portée de bloc

  • Avec, clause catch, let (ES6), const (ES6) génère la portée du bloc

  • La portée lexicale se soucie de l'endroit où la fonction est déclarée

  • La portée dynamique se soucie de l'endroit où la fonction est appelée

  • Le chaînage de portées lexicales est basé sur l'imbrication de portées

  • La chaîne de portées de portée dynamique est basée sur la pile d'appels

Ce qui précède vise à clarifier le contenu de la portée lexicale, statique, dynamique, des fonctions et des blocs dans JS. Pour plus de contenu connexe, veuillez faire attention à PHP Chinese Net (www.php.cn) !


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