Vues de contexte JavaScript

Bonjour encore! Nous avons déjà écrit qu'à la fin du mois de septembre dans OTUS un nouveau flux du cours "Fullstack JavaScript Developer" va commencer. En prévision du début des cours, nous continuons à partager avec vous des articles protégés spécialement pour les étudiants du cours. Aujourd'hui, nous allons examiner les types de contexte en JavaScript. Allons-y.

Auteur de l'article: Pavel Yakupov




Le but de cet article est de permettre au lecteur de comprendre les concepts de base des étendues utilisées en JavaScript.

La portée est l'une des choses les plus importantes de JavaScript (et elle a sa place dans la plupart des langages de programmation modernes). La portée est associée à la longue durée de vie d'une variable ou d'une fonction, à l'accès, à la visibilité des variables et à d'autres choses.

Pourquoi avons-nous besoin de cette portée?


La portée des langages de programmation remplit les fonctions suivantes:
Sécurité (encapsulation) - les variables et les fonctions ne sont disponibles que lorsqu'elles sont nécessaires.
Élimine le conflit des noms de variables. La présence de portées vous permet de ne pas «vider» toutes les variables dans un même tas, simulant des espaces de noms (namespace).
Réutilisation du code - le code écrit peut alors être utilisé, en évitant les effets "étrangers".

Types de portées


Au niveau le plus simple, en JavaScript, il existe deux étendues - locale et globale.

Dans cet article, nous aborderons également une portée telle que lexicale et bloc.

Portée mondiale


Lorsque vous ouvrez un document en JavaScript et commencez à écrire du code, vous tombez dans la portée globale.

Tout ce qui est créé dans la portée globale - variables, fonctions - est accessible de n'importe où dans le programme. En outre, les variables globales sont disponibles tout le temps que votre application est en cours d'exécution et sont supprimées uniquement lorsque le programme a terminé son travail.

De nombreux nouveaux arrivants utilisent au début trop souvent des variables globales - c'est un peu plus facile à programmer, mais cela est considéré comme une mauvaise pratique, et conduit souvent à des programmes instables qui utilisent finalement beaucoup plus de mémoire qu'ils n'en ont réellement besoin. Après tout, si les variables étaient encapsulées de manière fiable dans les fonctions dans lesquelles elles sont utilisées, à la fin de la fonction, elles seraient supprimées de la mémoire à l'aide du Garbage collector et cesseraient d'occuper la mémoire client, qui n'est pas infinie.

Portée locale


Les variables déclarées localement ne sont disponibles que dans l'étendue où elles ont été déclarées.

La façon la plus simple de créer une nouvelle étendue est de créer une nouvelle fonction. Une variable créée à l'intérieur d'une fonction n'est accessible que de l'intérieur. De plus, la portée locale peut être obtenue en utilisant la portée de bloc (sera discutée ci-dessous).

function foo(){ let x = 15; } //console.log(x); error { let y = 14; } // console.log(y);  error { var z = 13; } console.log(z); // var   , //        // -  13 

Portée lexicale


Alors, quelle est la portée lexicale? En termes simples, il s'agit de la capacité d'une fonction interne d'accéder à un périmètre externe. Ici, il convient de se tourner vers la pratique des fermetures. Vous pouvez probablement écrire quelques articles supplémentaires à leur sujet, mais je vais vous donner rapidement un exemple classique:

 sum(5)(5) //    ? function sum(a){ var add = function(b){ return a+b; } return add; } console.log(sum(5)(5)); // 10   //      

Portée du bloc


Jusqu'à présent, nous n'avons discuté que des étendues associées au fonctionnement des fonctions et des accolades {}, et nous avons discuté des différences dans le fonctionnement de var et laissé indirectement.

Comment fonctionne la directive var? Lorsqu'une variable est déclarée en l'utilisant dans la portée globale, le nom de la variable est affecté en tant que propriété à l'objet de fenêtre globale (si nous voulons dire le navigateur) et y reste tout le temps où le programme s'exécute. En même temps, comme une portée de bloc, telle que {} (et si, pour, tandis que et tous les autres sont inclus de manière assez logique).

De plus, il y a une autre caractéristique de let et const - déclarés dans la même portée, alors ils ne peuvent pas être déclarés à nouveau dans la même portée (enfin, l'insatisfaction de l'interpréteur semble tout à fait logique ici).

 let x = 15; console.log(x); //   { let x = 16; //       console.log(x) //          let x = 17; //        ,         } 

nouvelle fonction


Caractéristiques de la portée lors de la déclaration d'une nouvelle fonction comme "nouvelle fonction". Cette option pour créer une fonction est rarement utilisée, mais parfois elle peut être requise.
Exemple de syntaxe:

 //let newFunc = new Function([arg1, arg2…argN], functionBody); let mult = new Function('a', 'b', 'return a * b'); console.log(mult(3,4)); 

Habituellement, une fonction se souvient de sa naissance (environnement lexical), mais lorsqu'une fonction est créée à l'aide de la nouvelle construction Function, elle n'écrit pas les variables d'environnement qui l'entourent, comme dans une situation normale, mais uniquement celles déclarées globalement.

 //   ,      ()()     let a = 3; function outerFunc() { var a = 2; var func = new Function('console.log(a*a)'); return func; } outerFunc()(); // 9,    window 

Levage (augmentation des variables)


En discutant de la portée, nous n'avons pas pu aborder le sujet de l'augmentation de la portée des variables. L'interpréteur qui lit le code le lit en fait deux fois: il lit les fonctions déclarées comme déclaraton de fonction et lit les variables globales déclarées globales à l'aide de la variable var. Cependant, les variables ne sont pas enregistrées par leurs valeurs déclarées, mais par la valeur non définie.

 console.log(x); // undefined var x = 15; console.log(y);// error let y = 13; 

Que ce sujet ne se rapporte qu'indirectement aux zones de visibilité, mais parfois cette connaissance peut être utile.

Merci à tous! J'espère que cet article a été utile à quelqu'un!



Liens utiles:

developer.mozilla.org/en-US/docs/Glossary/Scope
developer.mozilla.org/en/docs/Web/JavaScript/Closures
2ality.com/2015/02/es6-scoping.html
learn.javascript.ru/new-function
habr.com/en/company/otus/blog/466873

Source: https://habr.com/ru/post/fr467631/


All Articles