Voici la méthode utilisée par Douglas Crockford pour définir les classes en javascript.
(certaines idées sont reprises dans pdf.js par ex)
Il détourne la notion de closure pour faire l'équivalent.
"module pattern"
Cela représente la définition d'un objet avec ses champs et ses méthodes.
Mais en javascript, c'est fait avec la notion de closure
L'exemple qui suit créé directement une instance, (--> 'singleton')
var singleton = (function () {
var privateVariable;
function privateFunction(x) {
...privateVariable...
}
return {
firstMethod: function (a, b) {
...privateVariable...
},
secondMethod: function (c) {
...privateFunction()...
}
};
} () );
singleton.firstMethod();
singleton.secondMethod();
version avec défintion de classe, constructeur avec paramètres :
/* version avec params passes au constructeur*/
var maclasse = function (z) {
// z est param du constructeur de maclasse
var nom = z || '?'; // z est utilise comme param optionnel
var v1;
function _f1(x) {
v1 = "test "+nom+" : ";
}
return {
firstMethod: function (a) {
_f1();
v1 = v1 + " 2";
document.write(v1+"<br>");
},
secondMethod: function () {
//_f1();
v1 = v1 + " 3";
document.write(v1+"<br>");
}
};
};
var inst1 = maclasse("inst1");
var inst2 = maclasse();
document.write("inst1<br>");
inst1.firstMethod();
inst1.secondMethod();
document.write("inst2<br>");
inst2.firstMethod();
inst2.secondMethod();
resultat
Test javascript
Test javascript 2
inst1
test inst1 : 2
test inst1 : 2 3
inst2
test ? : 2
test ? : 2 3
On a bien créé 2 instances de la classe 'maclasse'.
Une instance a eu un paramètre lors du constructeur, l'autre non.
On peut continuer à définir des classes avec cette méthode, mais c'est tres lourd et tres lent !
TOUTE LA SUITE EST A TESTER/VERIFIER
Ajout d'un champ à un objet global, en reprenant l'idée du singleton
GLOBAL.methodical = (function () {
var privateVariable;
function privateFunction(x) {
...privateVariable...
}
return {
firstMethod: function (a, b) {
...privateVariable...
},
secondMethod: function (c) {
...privateFunction()...
}
};
} () );
ajout de methodes a un objet
(function () {
var privateVariable;
function privateFunction(x) {
...privateVariable...
}
GLOBAL.firstMethod = function (a, b) {
...privateVariable...
};
GLOBAL.secondMethod = function (c) {
...privateFunction()...
};
} () );
functional inheritance
function gizmo(id) {
return {
id: id,
toString: function () {
return "gizmo "+ this.id;
}
};
}
function hoozit(id) {
var that = gizmo(id);
that.test = function (testid) {
return testid === this.id;
};
return that;
}
functional inheritance
version avec champs prives
function gizmo(id) {
return {
toString: function () {
return "gizmo "+ this.id;
}
};
}
function hoozit(id) {
var that = gizmo(id);
that.test = function (testid) {
return testid === this.id;
};
return that;
}
functional inheritance
version avec 'shared secrets'
function gizmo(id, secret) {
secret = secret || {}
secret.id = id
return {
toString: function () {
return "gizmo "+ secret.id;
}
};
}
function hoozit(id) {
var secret = {}; /* final */
var that = gizmo(id, secret);
that.test = function (testid) {
return testid === secret.id;
};
return that;
}
super methods (???)
function hoozit(id) {
var secret = {}; /* final */
var that = gizmo(id, secret);
var super_toString = that.toString;
that.test = function (testid) {
return testid === secret.id;
};
that.toString = function () {
return super_toString.apply(that);
};
return that;
}