Apprendre a créer ses classes javascript grace à actionscript
Je me suis mis récemment à la programmation orientée objet avec Javascript, je n'ai pas pu m'empêcher de faire le parallèle avec l'AS1, tellement il y a de similitudes.
Voici un petit tutorial pour les personnes qui, avec l'arrivée de Apollo, voudraient se lancer dans un Javascript un petit peu plus avancé. Je suis sûr que les personnes qui gèrent bien l'AS1 retrouverons très rapidement leurs repères.
Les bases
Tous les codes présentés dans cette section fonctionnent aussi bien en Javascript qu'avec Flash. Je vous conseille de tester, il vous faudra seulement remplacer les fonctions alert
par des trace
.
Créer une classe
//**************************** // créer une classe MaClasse = function () { // le constructeur alert ('Le constructeur est appelé'); // propriété publique this.publicVar = "toto"; // proriété privée var privateVar = "titi"; // function membre this.maFunction = function () { alert ("Appel de la fonction maFunction() \n publicVar et privateVar : "+this.publicVar+"/"+privateVar); } } //**************************** // créer une instance de la classe // trace : Le constructeur est appelé var instMaClasse = new MaClasse (); // test de la variable privée // trace : On ne peut pas accéder à cette variable privée if (!instMaClasse.privateVar) alert ('On ne peut pas accéder à cette variable privée'); // et appel de fonction // trace : Appel de la fonction maFunction() // publicVar et privateVar : toto/titi instMaClasse.maFunction (); // Les classes sont détruites avec delete et ne comportent pas de destructeurs delete instMaClasse;
Comme en AS1, en Javascript, lorsque je crée une fonction, je crée un nouvel objet. L'utilisation de this
et de var
permet d'associer facilement des fonctions et des variables à cet objet.
MaClasse = function () { // le constructeur alert ('Le constructeur est appelé'); // propriété publique this.publicVar = "toto"; // propriété privée var privateVar = "titi"; // fonction membre this.maFunction = function () { alert ("Appel de la fonction maFunction() \n publicVar et privateVar : "+this.publicVar+"/"+privateVar); } }
La création des fonctions et des variables d'instances ( contraire d'une fonction ou d'une variable statique ) se fait dans le constructeur.
this.maFunction = function () { … }
crée une fonctionthis.publicVar = “toto”;
crée une variable
Le mot clef var
limite la portée d'une variable au contexte de la fonction, elle n'est donc pas accessible à l'extérieur de la fonction. On peut donc l'utiliser pour créer une variable ou une fonction privée.
var privateVar = “private variable”;
crée une variable privée, cela fonctionne aussi pour les fonctions privées.
Voici quelques tests qui vous permettent de voir le resultat aussi bien en Javascript que sous flash ( en remplacant bien sur alert (…)
par trace (…)
).
//**************************** // créer une instance de la classe // trace : Le constructeur est appelé var instMaClasse = new MaClasse (); // test de la variable privée // trace : On ne peut pas accéder à cette variable privée if (!instMaClasse.privateVar) alert ('On ne peut pas accéder à cette variable privée'); // et appel de fonction // trace : Appel de la fonction maFunction() // publicVar and privateVar : toto/titi instMaClasse.maFunction (); // Les classes sont détruites avec delete et ne comportent pas de destructeurs delete instMaClasse;
Ce code affiche le resultat suivant :
- Le constructeur est appelé
- On ne peut pas accéder à cette variable privée
- Appel de la fonction maFunction()
publicVar and privateVar : toto/titi
Créer une variable ou une fonction statique
Cet exemple est intéressant, car il permet d'insister sur le fait que les types sont eux aussi des objets. On va utiliser ce concept pour créer des variables propres non pas à une instance de classe, mais à la classe elle-même.
//**************************** // Créer une variable et une fonction statique Circle = function (radius) { this.radius = radius; } // variable statique Circle.pi= 3.14; // fonction statique Circle.getPiValue = function () { alert (Circle.pi); }
Circle.pi= 3.14
crée une variable statiqueCircle.getPiValue = function () {…}
crée une fonction statique
Dans ce code de test, on voit que l'on peut accéder à ces propriétés et fonctions statiques sans avoir à créer d'instance de la classe. Elles ne sont, par contre, pas accessibles à partir d'une instance de classe. On peut aussi parler de propriétés et fonctions de classes.
// trace: 3.14 Circle.getPiValue (); // trace: undefined myCircle=new Circle (1); alert (myCircle.pi);
Ajouter dynamiquement des fonctions
//***************************** // function dynamique // introduction au prototype Circle.prototype.getPerimeter = function () { return 2*Circle.pi*this.radius; } myCircle = new Circle (1); alert (myCircle.getPerimeter ());
La proprieté prototype permet d'assigner aux futurs instances de la classe de nouvelles fonctions et propriétés. Les instances créées avant la modification du prototype sont aussi affectées.
J'utilise cet exemple pour expliquer le fonctionnement de prototype
. Personnellement, je n'aime pas l'utiliser pour mes propres classes, je trouve que la modification d'une classe après sa déclaration n'est pas une bonne pratique. Par contre, on peut utiliser prototype
pour étendre les classes natives de Javascript comme Array ou HTMLelement.
Héritage
Ne rêvons pas, il n'est pas possible de faire un héritage aussi simplement qu'en AS2. Cependant, avec quelques lignes de code on peut avoir un résultat “similaire”.
Dans l'exemple suivant, je veux créer une classe sphère qui hérite des méthodes et propriétés de la classe précédente Circle.
Sphere = function (radius) { // appele this.Circle (radius) comme si Circle était une fonction de this // ceci permet d'appeler le constructeur de Circle sans générer d'erreurs // cette ligne va éxecuter le code suivant : // this.this.radius = radius; Circle.call (this, radius); this.isASphere = function () { alert ('oui, c\'est une sphère'); } } // copie les fonctions ajoutées dynamiquement si c'est nécessaire Sphere.prototype = Circle.prototype; // les fonctions et variables statiques, ainsi que les les functions // dynamiques doivent être copiées une à une ..... Sphere.pi = Circle.pi; Sphere.getPiValue = Circle.getPiValue; mySphere = new Sphere (3); // trace : Yes, it's sphere mySphere.isASphere (); // trace : 18.84 alert (mySphere.getPerimeter ());
L'héritage se fait en trois étapes :
Circle.call (this, radius);
On exécute dans notre constructeur le constructeur de la classe parente. C'est lui qui va rajouter les méthodes et propriétés de Circle à la classe Sphere.
La fonction call
est l'équivalent de this.Circle (radius);
qui génèrerait une erreur puisque circle n'est pas membre de notre classe .
Sphere.prototype = Circle.prototype;
On récupère les méthodes et propriétés non définies dans le constructeur grâce à l'objet prototype
. Si vous n'utilisez pas les prototypes, cette étape n'est pas nécessaire.
Sphere.pi = Circle.pi;…
Enfin, la partie la plus problématique selon moi, on doit récupérer une à une toutes les variables et fonctions statiques de la classe mère.
En savoir plus
