Quelle est une brève introduction au scoping lexical ?
Réponses
Trop de publicités?J'espère que cela vous aidera, voici ma tentative de définition un peu plus abstraite :
Portée lexicale : L'accès ou la portée que quelque chose (par exemple une fonction ou une variable) a à d'autres éléments du programme, tel que déterminé par sa position dans le code source.
En passant, ma logique ici se base simplement sur les définitions de :
Lexical : relatif aux mots ou au vocabulaire d'une langue (spécifiquement le mot en tant que séparé de sa grammaire ou de sa construction) {dans notre cas - un langage de programmation}.
Portée (nom) : la gamme d'opérations {dans notre cas, la gamme est : ce à quoi on peut accéder}.
Note, l'original de 1960 définition de Lexical Scope
de la spécification ALGOL 60 est bien plus concise que ma tentative ci-dessus :
Portée lexicale : la partie du code source dans laquelle s'applique la liaison d'un nom avec une entité. fuente
Voici un angle différent de cette question que nous pouvons obtenir en prenant un peu de recul et en examinant le rôle du cadrage dans le cadre plus large de l'interprétation (exécution d'un programme). En d'autres termes, imaginez que vous construisiez un interpréteur (ou un compilateur) pour un langage et que vous soyez responsable du calcul de la sortie, étant donné un programme et une entrée pour celui-ci.
L'interprétation implique de tenir compte de trois éléments :
-
État - à savoir, les variables et les emplacements mémoire référencés sur le tas et la pile.
-
Les opérations sur cet état - à savoir, chaque ligne de code dans votre programme
-
El environnement dans laquelle une opération fonctionne - à savoir, la projection de état sur une opération.
Un interprète commence à la première ligne de code d'un programme, calcule son environnement, exécute la ligne dans cet environnement et capture son effet sur l'état du programme. Il suit ensuite le flux de contrôle du programme pour exécuter la ligne de code suivante, et répète le processus jusqu'à la fin du programme.
La manière dont vous calculez l'environnement pour une opération quelconque passe par un ensemble formel de règles définies par le langage de programmation. Le terme "binding" est fréquemment utilisé pour décrire la mise en correspondance de l'état global du programme avec une valeur de l'environnement. Notez que par "état général", nous n'entendons pas l'état global, mais plutôt la somme totale de chaque définition atteignable, à tout moment de l'exécution).
Il s'agit du cadre dans lequel le problème de cadrage est défini. Passons maintenant à la partie suivante, à savoir quelles sont nos options.
- En tant qu'implémenteur de l'interpréteur, vous pourriez vous simplifier la tâche en rendant l'environnement aussi proche que possible de l'état du programme. En conséquence, l'environnement d'une ligne de code serait simplement défini par l'environnement de la ligne de code précédente avec les effets de cette opération appliqués à celle-ci, que la ligne précédente soit une affectation, un appel de fonction, le retour d'une fonction ou une structure de contrôle telle qu'une boucle while.
C'est l'essentiel de cadrage dynamique L'environnement dans lequel s'exécute un code est lié à l'état du programme tel que défini par son contexte d'exécution.
- O Vous pouvez donc imaginer qu'un programmeur utilise votre langage et lui simplifier la tâche en lui permettant de garder la trace des valeurs que peut prendre une variable. Il y a beaucoup trop de chemins et trop de complexité dans le raisonnement sur le résultat de la totalité des exécutions passées. Portée lexicale aide à faire cela en restreignant l'environnement actuel à la portion de l'état défini dans le bloc, la fonction ou toute autre unité de portée actuelle, et son parent (c'est-à-dire le bloc entourant l'horloge actuelle, ou la fonction qui a appelé la présente fonction).
En d'autres termes, avec portée lexicale l'environnement que tout code voit est lié à l'état associé à une portée définie explicitement dans le langage, comme un bloc ou une fonction.
Voici une explication dans le cas de R.
Ce sujet est fortement lié à l'intégration bind
et introduite dans l'ECMAScript 6 Fonctions des flèches . C'était vraiment ennuyeux, car pour chaque nouvelle méthode de "classe" (fonction en fait) que nous voulions utiliser, nous devions bind
ceci afin d'avoir accès à la portée.
Par défaut, JavaScript ne définit pas son champ d'application en matière de this
sur les fonctions (il ne définit pas le contexte en this
). Par défaut, vous devez indiquer explicitement quel contexte que vous voulez avoir.
El fonctions de la flèche obtient automatiquement ce qu'on appelle portée lexicale (avoir accès à la définition de la variable dans son bloc contenant). Lorsque vous utilisez fonctions de la flèche il lie automatiquement this
à l'endroit où la fonction flèche a été définie en premier lieu, et l'élément contexte de cette fonctions de la flèche est le bloc qui le contient.
Voyez comment cela fonctionne en pratique sur les exemples les plus simples ci-dessous.
Avant les fonctions de la flèche (pas de portée lexicale par défaut) :
const programming = {
language: "JavaScript",
getLanguage: function() {
return this.language;
}
}
const globalScope = programming.getLanguage;
console.log(globalScope()); // Output: undefined
const localScope = programming.getLanguage.bind(programming);
console.log(localScope()); // Output: "JavaScript"
Avec fonctions de flèche (portée lexicale par défaut) :
const programming = {
language: "JavaScript",
getLanguage: function() {
return this.language;
}
}
const arrowFunction = () => {
console.log(programming.getLanguage());
}
arrowFunction(); // Output: "JavaScript"
J'apprends normalement par l'exemple, et voici un petit quelque chose :
const lives = 0;
function catCircus () {
this.lives = 1;
const lives = 2;
const cat1 = {
lives: 5,
jumps: () => {
console.log(this.lives);
}
};
cat1.jumps(); // 1
console.log(cat1); // { lives: 5, jumps: [Function: jumps] }
const cat2 = {
lives: 5,
jumps: () => {
console.log(lives);
}
};
cat2.jumps(); // 2
console.log(cat2); // { lives: 5, jumps: [Function: jumps] }
const cat3 = {
lives: 5,
jumps: () => {
const lives = 3;
console.log(lives);
}
};
cat3.jumps(); // 3
console.log(cat3); // { lives: 5, jumps: [Function: jumps] }
const cat4 = {
lives: 5,
jumps: function () {
console.log(lives);
}
};
cat4.jumps(); // 2
console.log(cat4); // { lives: 5, jumps: [Function: jumps] }
const cat5 = {
lives: 5,
jumps: function () {
var lives = 4;
console.log(lives);
}
};
cat5.jumps(); // 4
console.log(cat5); // { lives: 5, jumps: [Function: jumps] }
const cat6 = {
lives: 5,
jumps: function () {
console.log(this.lives);
}
};
cat6.jumps(); // 5
console.log(cat6); // { lives: 5, jumps: [Function: jumps] }
const cat7 = {
lives: 5,
jumps: function thrownOutOfWindow () {
console.log(this.lives);
}
};
cat7.jumps(); // 5
console.log(cat7); // { lives: 5, jumps: [Function: thrownOutOfWindow] }
}
catCircus();
- Réponses précédentes
- Plus de réponses
100 votes
Dans le podcast 58, Joel encourage les questions de ce genre car il souhaite que SO devienne LE lieu où l'on trouve des réponses, même si elles ont déjà été données ailleurs. Cette question est valable, même si on pourrait la formuler de manière un peu plus polie.
0 votes
Et puis surtout fr.wikipedia.org/wiki/Scope_(programmation) qui contient un bel exemple (Pascal/Delphi) de scopes imbriqués dans des procédures imbriquées.
7 votes
@rahul Je comprends que c'est une vieille question. Mais je suis sûr que même en 2009, SO s'attendait à ce que les demandeurs mettent en quelques efforts de base pour le résoudre. En l'état actuel des choses, il ne montre pas tout effort du tout. C'est peut-être pour cela qu'il a été descendu par beaucoup ?
16 votes
Il est possible que l'auteur de la question ne parle pas (ou n'ait pas parlé) couramment l'anglais lorsqu'il a écrit cette question.
38 votes
La question est polie, il dit juste ce qu'il veut. Vous êtes libre de répondre. Pas besoin de politesse excessive ici.
33 votes
Je pense que les questions de ce genre sont excellentes car elles permettent de créer du contenu pour les OS. IMO, qui se soucie si la question n'a pas d'effort... les réponses auront un grand contenu et c'est ce qui compte sur ce forum.
6 votes
Je suis d'accord avec @Jwan622 une question n'a pas besoin d'être verbeuse pour être une bonne question.