mardi 19 octobre 2010
Avez-vous digéré le piège JavaScript d'hier ? Par curiosité, avez-vous mis vos connaissances à l'épreuve au quiz JavaScript avancé ? Si oui, quel pointage avez-vous obtenu ?
Si vous êtes disposés à continuer, je suis prêt à m'attaquer au piège suivant.
var a = 1,Qu'est-ce que ce code vous suggère ? Est-ce possible qu'une variable possède le même nom qu'une fonction ? Si oui, la valeur de la variable a pourrait être transformée par la fonction a(). ou encore, l'appel à alert(a) affichera-t-elle la valeur de la variable ou le résultat de la fonction ?
b = function a(x) {
x && a(--x);
};
alert(a);
Exécutons le code ci-dessous pour mieux comprendre le fonctionnement interne :
console.log(typeof a); // numberRésultat : alert(a) affichera 1
console.log(a); // 1
console.log(b); // a(x)
console.log( a(7) ); // erreur : a is not a function
L'explication est que la fonction peut s'appeller a car elle n'entre pas en conflit avec la variable a puisqu'elles ne sont pas dans la même portée (la fonction est dans la portée de b alors que la variable est dans la portée globale). En fait, la fonction a, qui aurait pu être anonyme (sans nom) est une définition de fonction qui est assigné à b, ce qui fait qu'on ne peut pas appeler la fonction a() directement, sauf à l'intérieur de lui-même (concept de récursivité). Par contre, on peut l'appeler à l'aide de b() qui est reconnu dans la portée globale :
b(7); // appel de la fonction a() en passant 7 comme paramètreSi on glisse une instruction alert(x) ou console.log(x) pour suivre la trace au début de la fonction a(), on verra que la fonction est appelée récursivement (elle s'appelle elle-même) : 7, 6, 5, 4, 3, 2, 1, 0. À la ligne de code x && a(--x), si x vaut 0, la valeur zéro est considérée comme false dans l'évaluation de la condition (les conditions if(!0) et if(false) sont équivalentes). Dès que false est rencontré dans le ET logique, les conditions suivantes ne sont pas évaluées, ce qui met fin à la récursivité. Sinon, la fonction se rappelle elle-même en utilisant la valeur de x décrémentée (opérateur --).