jeudi 14 janvier 2010
Syntaxe particulière des appels de fonctions JavaScript
Publié par Infinite Loop, à 20 h 06
2 commentaires
Tout comme moi, vous avez peut-être déjà remarqué la syntaxe JavaScript suivante où la définition de la fonction est elle-même suivie de parenthèses :
var object = function(){}();Peut-être que vous ne vous êtes pas posé la question à savoir ce qu'elles faisaient là ? Peut-être êtes-vous curieux de le savoir ? En fait, je l'ignorais jusqu'à ce que je commence à faire la lecture du code de jQuery et Prototype pour comprendre le fonctionnement interne et apprendre quelques trucs sur le tas (ne m'en voulez pas, je suis surtout spécialisé dans le back-end (server-side) des applications web).
Ouvrez le code source et remarquez la syntaxe de ces librairies.
var object = function(){Pour constater ce qui se passe, on voit qu'il y a une variable obj et qu'on lui assigne le résultat d'une fonction. La variable ne contiendra pas le corps de la fonction anonyme mais bien ce que la fonction retourne. Les parenthèses à la fin indiquent à l'engin JavaScript qu'il doit exécuter immédiatement la fonction dès qu'elle est interprétée.
// code
}();
var result = function(){Qui est équivalent à la forme alternative :
return 'Hello World';
}();
// Hello World
alert(result);
var fct = function(){Remarquez dans l'exemple précédent que la fonction n'est pas suivie par (), ce qui veut dire qu'elle n'est pas exécutée. Le corps de la fonction se trouve dans la variable fct qu'on peut ensuite l'appeler avec fct().
return 'Hello World';
};
alert(fct());
L'autre particularité qu'il faut retenir est qu'en utilisant la première forme avec les parenthèses, il est possible de passer un argument, ce qui explique bien des choses dans le fonctionnement de jQuery (...(window);) et Prototype (...(Element.Methods);).
var result = function(text){En passant, la librairie jQuery 1.4 est officiellement sortie aujourd'hui.
return text;
}('Hello World');
alert(result);
Cette syntaxe a pour principal avantage de créer des objets ou des classes javascript possédant des attributs privés ou publiques comme dans n'importe quel langage objet.
Deux exemples :
var MyObj = function() {
var attr = "aaa";
return {
getAttr : function() {
return attr;
}
};
}();
Dans ce code, l'attribut "attr" est défini dans la fonction anonyme, je n'y ai donc pas accès. Par contre j'ai accès à son getter "getAttr".
Donc si je fais :
console.log(MyObj.getAttr());
console.log(MyObj.attr);
Le premier va m'afficher "aaa" tandis que le second va m'afficher "undefined".
Deuxième exemple, cette fois-ci avec une classe :
var MyClass = function() {
this.attr = "bbb";
return function() {
return {
getAttr: function() {
return attr;
}
}
};
}();
En appelant le code suivant :
var MyObj2 = new MyClass();
console.log(MyObj2.getAttr());
console.log(MyObj2.attr);
Le premier appel va m'afficher "bbb" tandis que le second va m'afficher "undefined".
Exemple très pertinent. Merci!