La portée et les fonctions en Javascript

Entre l’écriture de deux gros articles, et la finition de mon mémoire, il s’est passé un peu de temps sans qu’un nouvel article sorte. Je profite d’un peu de disponibilité pour venir prendre soin de mon blog, car il faut bien de temps en temps.

Je vais parler de la portée des variables en JavaScript, qui je trouve est quelque chose d’important mais auquel on ne fait prête pas forcément attention. Portée aussi communément appelée « scope » en Anglais et même de façon internationale, donc j’utiliserais plutôt cette dernière dénomination dans la suite de l’article.

Dans les langages classiques compilés comme le C, C++, Java, C# … la portée est au niveau du bloc de structure. Chaque variable dans une condition, une boucle, une fonction … se trouve dans un scope isolé.

Par exemple dans ce code C :

int main(void) {
    byte adr = 2;
    println("%d", adr);    // affiche 2
    if(adr ==2) { 
        byte adr = 4; 
        println("%d", adr); // affiche 4 
    } 
    println("%d", adr); // affiche 2 
}

Vous me direz que c’est basique et logique, je vous répondrais qu’effectivement il n y a rien de complexe là-dedans … comparons maintenant avec un exemple basique mais en Javascript cette fois :

function init() {
	var adr = 2;
        console.log(adr);  // affiche 2
	if (adr == 2) {
		var adr = 4;
                console.log(adr);   // affiche 4
	}
	console.log(adr);   // affiche 4
}

On remarque ici, que la variable adr initiale (=2) va voir sa valeur écrasée dans le bloc conditionnel if. Donc, contrairement aux langages compilés connus (C, C++, …) le Javascript créé un scope différent a chaque nouvelle fonctions.

Et bien, ne faites pas cette tête, si vous avez une énorme fonction en Javascript, et que vous voulez naturellement ne pas rendre accessible des tas de variables inutiles qui ne sont utilisées que dans une petite partie de la fonction : c’est possible. On utilise une petite technique pour exécuter du code dans plusieurs scopes différents à l’intérieur d’une fonction en Javascript :

function init() {
	var adr = 2;
        console.log(adr);  // affiche 2
	if (adr == 2) {
                (function() {
		      var adr = 4;
                       console.log(adr);   // affiche 4
                }());
	}
	console.log(adr);   // affiche 2
}

Voilà ! Vous deviez sûrement connaître les fonction anonymes en Javascript, mais peut-être n’avez vous jamais vraiment pensé à TOUTES les utilités de celles-ci. En voici une. Il est intéressant d’observer comment le langage se comporte à l’exécution.

Une autre petite expérience intéressante serait de tester l’ordre d’exécution sur les deux manières de déclarer une fonction en Javascript :

(function () {
	work(); // TypeError "work is not a function"
	sleep();  // sleep va s’exécuter
	var work = function () { 
		console.log("cette fonction ne va pas s’exécuter");
	}
	function sleep() { 
		console.log("celle-ci va s’exécuter en revanche");
	}
}());

On voit ici que le scope ne connaît pas la fonction work(), mais connais sleep(). Selon le type de déclaration, la fonction sera exécutée ou non. Dans l’exemple ci-dessus, la fonction work est affectée à une variable locale, mais n’est pas reconnue dans le flot d’exécution direct : il faudrait appeler la fonction après l’avoir affectée. Tandis que la fonction sleep déclarée de manière générale, est immédiatement disponible dans le scope, peut importe l’endroit depuis laquelle est elle appelée : tant que c’est dans le scope qui connait sleep !

Ce fut bref et basique, mais c’est parfois en prêtant attention aux bases d’un fonctionnement, qu’on évite des problèmes futurs lors de nos conception d’applications. Happy coding!

Laisser un commentaire