Cycymomo
7/23/2013 - 7:46 AM

héritage délégation javascript

héritage délégation javascript

En JavaScript, on ne teste pas qu'un objet appartient à telle classe ou implémente telle interface. Cela n'a pas de sens car un objet JavaScript n'entre dans aucun moule préalablement défini

En gros, en JavaScript, tu ne crées pas un objet à partir d'un moule (classe) qui doit implémenter telle interface, mais tu crées un objet A à partir d'un autre objet B. B devient alors le prototype de A. Le prototype "racine" étant [CODEINLINE]Object[/CODEINLINE]. Le nouvel objet B ainsi créé à partir de A aura ses propres méthodes/attributs et aura également accès à celles de A, puis ensuite à celles du prototype de A, etc. On parle de chaîne de prototype. Si la propriété/méthode n'est pas dans B, on check dans son prototype A, puis dans le prototype du prototype A, etc, jusqu'à remonter la pile jusqu'à [CODEINLINE]Object[/CODEINLINE].

Un "équivalent" de l'interface serait plutôt de tester la présence d'attributs ou de méthodes.

En effet, JavaScript répond au style "[URL="http://fr.wikipedia.org/wiki/Duck_typing"]duck typing[/URL]". Si mon objet à la méthode "coincoin()" et qu'il a un bec, alors cet objet est un canard. Sinon ce n'en est pas un.

Voici un cas ultra basique pour simuler une notion "d'interface". On check si l'objet courant possède les propriétés imposées par l'interface qui est en réalité un objet classique recensant les types de propriétés attendues. Attention, si l'objet courant contient plus de propriétés, ce bout de code ne le détecte pas. Bref, c'est simplement pour imager la chose :

// l'objet implémente - t - il l'interface ?
Object.prototype.implemente = function(interface){ 
  for(var prop in interface) if (interface.hasOwnProperty(prop)) {
    if(typeof this[prop] !== interface[prop] || typeof this[prop] === undefined)
      return false;
  }
  return true;
};


var interfaceCochon = {
  hasGroin: "boolean",
  groingroin: "function",
  couleur: "string"
}; 

var interfaceCanard = {
  hasBec: "boolean",
  coincoin: "function"
}; 

var objetCanard = {
  hasBec: true,
  coincoin: function() { console.log('coin coin'); }
}

console.log(objetCanard.implemente(interfaceCochon)); // false
console.log(objetCanard.implemente(interfaceCanard)); // true

Mais ça n'a pas de sens car c'est un langage dynamique. A la création de l'objet, peut-être que objetCanard se pliera aux exigences d'une interface quelconque. Mais quid de modifier ensuite l'interface ? Ou l'objet ?