
Le scope en Javascript : définition et explications.
Quatrième article de notre série : Javascript sous le capot ! Pour l’occasion, on fait un focus sur le scope en Javascript : scope de fonction et block scope. Bonne lecture !
Nous avons déjà entendu parler de Scope dans la partie 2 – Fonctionnement du moteur. Il s’occupait de collecter et garder une liste des variables déclarées. On avait également dit qu’il pouvait y avoir plusieurs Scopes.
Il y a même plusieurs types de Scope, allons donc voir ici plus en détail, ce concept.
La vision la plus simple pour commencer est de voir chaque fonction comme un Scope.
Chaque fonction va créer une bulle autour d’elle (le Scope), et seulement elle et ce qu’elle contient, pourra y accéder.
On peut voir les Scopes comme une succession de bulles, imbriquées les unes dans les unes. Une bulle parent ne pourra pas voir ce que contient les bulles enfants, seul l’inverse est possible : une bulle peut accéder à toutes les bulles qui l’englobe, mais aucune qu’elle englobe elle.
Un exemple très simple afin d’illustrer tout ça :
function bar(){
var a = 3;
function foo(){
var b = 5;
console.log(a); // 3
}
foo();
console.log(b); // ReferenceError
}
bar()
Dans le code ci-dessus, on voit que le Scope de bar contient a et foo(), et foo étant une fonction, elle a son propre Scope contenant lui-même b.
bar a donc accès uniquement à a et foo car b est à l’intérieur de sa bulle. Quant à lui, foo à accès a tout ce qui se trouve à l’extérieur, il peut donc utiliser a, en plus de b.
Cela a autant d’avantages que d’inconvénients : on peut avoir des variables facilement globales à une grande partie de code, seulement, ça peut être plus compliqué de gérer un très grand nombre de variables qui ne servent pas forcément partout, et c’est moins lisible en termes de clarté de code.
Même si le Scope de fonction est le type de Scope le plus commun, il en existe d’autres, dont un que vous avez surement déjà utilisé sans même vous en rendre compte : le Block scope.
Depuis ES6, deux nouveaux mots clés sont introduits : let et const.
Ces mots clés, qui ont l’air de fonctionner de la même manière que var (à part const qui a la particularité d’être finale), ont en fait une différence notable : ils attachent la variable au Scope du block auquel il est attaché.
Un block est tout simplement une paire d’accolade { .. }, tel qu’un if ou for.
var foo = true;
if (foo) {
let bar = 2;
console.log(bar);
}
console.log(bar); // ReferenceError
Cela peut vous paraître logique, mais, si à l’inverse vous déclarez bar avec un var à la place de let, vous obtiendrez 2 au lieu de ReferenceError au deuxième console.log.
Il est également possible d’utiliser des accolades sans mot clé, appelé explicit block, afin de juste créer un Scope :
var foo = 3;
{ // <-- explicit block
let bar = foo * 2;
console.log(bar);
}
console.log(bar) // ReferenceError
Un block scope peut s’avérer particulièrement utile afin de gérer de plus près la mémoire de votre application.
En effet, un block scope sera garbage collected directement à la sortie de celui-ci. C’est-à-dire que la mémoire utilisée sera libérée immédiatement.
var enormeImage = { .. };
process(enormeImage);
var btn = document.getElementById( "my_button" );
btn.addEventListener( "click", function click(evt){
console.log("button clicked");
}, false);
Si on prend en compte le code ci-dessus, le callback du click n’a pas besoin de enormeImage, la mémoire qu’elle occupe pourrait donc être libérée. Cependant, la fonction click va encapsuler tout le Scope afin de garder le contexte (appelé closure).
En utilisant un block scope, vous pouvez contrôler ce comportement, en vous assurant que la mémoire n’est pas utilisée pour rien :
{
let enormeImage = { .. };
process(enormeImage);
}
var btn = document.getElementById( "my_button" );
btn.addEventListener( "click", function click(evt){
console.log("button clicked");
}, false);
Comme la variable enormeImage est déclarée avec le mot clé let, elle sera attachée au block qui l’englobe (ici un explicit block). De ce fait, cette variable ne pourra jamais être utilisée en dehors de ce Scope, donc la mémoire sera automatiquement libérée.
Pour voir ou revoir les autres parties de notre série sur le JS, c’est par ici :
Explication du fonctionnement de Callback queue & Event loop en Javascript.
Comment faire un cahier des charges d’application qui soit à la fois clair, complet mais pas trop long, et qui donne envie aux agences de travailler avec vous ? En tant que prestataire de développement lyonnais, on nous a souvent posé cette question ! Et ça tombe bien, comme on a souvent l’habitude de voir passer des demandes de réalisation de projet informatique et de les étudier, on a justement un avis sur la question :) Dans cet article, vous retrouvez quelques explications et conseils pour la réalisation du cahier des charges informatique, et aussi un modèle de cahier des charges d’application pour vous aider !
Dans le monde de la programmation web, ces dernières années ont donné lieu à une explosion pure et simple des frameworks ! Ils ont progressivement pris une place considérable dans nos vies de développeurs, et pourtant… faut-il vraiment les utiliser