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 rendre son site web ou son application web accessible en 2021 ?
Il est possible de connecter Qlikview à une base de données MySql. Nous allons voir comment faire au travers d’un environnement windows.