685 votes

Quelles techniques peuvent être utilisées pour définir une classe en JavaScript, et quels sont leurs avantages ?

Je préfère utiliser la POO dans les projets de grande envergure comme celui sur lequel je travaille en ce moment. Je dois créer plusieurs classes en JavaScript mais, si je ne me trompe pas, il y a au moins deux façons de procéder. Quelle serait la syntaxe et pourquoi le faire de cette façon ?

Je voudrais éviter d'utiliser des bibliothèques tierces - du moins dans un premier temps.
En cherchant d'autres réponses, j'ai trouvé l'article Programmation orientée objet avec JavaScript, Partie I : Héritage - Doc JavaScript qui traite de la programmation orientée objet en JavaScript. Y a-t-il une meilleure façon de faire de l'héritage ?

741voto

Triptych Points 70247

Voici la façon de procéder sans utiliser de bibliothèques externes :

// Define a class like this
function Person(name, gender){

   // Add object properties like this
   this.name = name;
   this.gender = gender;
}

// Add methods like this.  All Person objects will be able to invoke this
Person.prototype.speak = function(){
    alert("Howdy, my name is" + this.name);
};

// Instantiate new objects with 'new'
var person = new Person("Bob", "M");

// Invoke methods like this
person.speak(); // alerts "Howdy, my name is Bob"

La vraie réponse est beaucoup plus complexe que ça. Par exemple, les classes n'existent pas en JavaScript. JavaScript utilise un prototype -Le schéma d'héritage est basé sur le principe de l'héritage.

En outre, il existe de nombreuses bibliothèques JavaScript populaires qui ont leur propre style d'approximation des fonctionnalités de type classe en JavaScript. Il est conseillé de consulter au moins Prototype y jQuery .

Décider lequel d'entre eux est le "meilleur" est un excellent moyen de lancer une guerre sainte sur Stack Overflow. Si vous vous lancez dans un projet plus vaste à forte intensité de JavaScript, il vaut la peine d'apprendre une bibliothèque populaire et de faire les choses à sa manière. Je suis un gars de Prototype, mais Stack Overflow semble pencher vers jQuery.

S'il n'y a qu'une seule façon de le faire, sans aucune dépendance à l'égard de bibliothèques externes, la façon dont j'ai écrit est à peu près la bonne.

213voto

Jörg W Mittag Points 153275

La meilleure façon de définir une classe en JavaScript est de ne pas en définir.

Sérieusement.

Il existe plusieurs variantes de l'orientation objet, dont certaines sont les suivantes :

  • OO basé sur les classes (introduit pour la première fois par Smalltalk)
  • OO basé sur des prototypes (introduit pour la première fois par Self)
  • OO basé sur les multiméthodes (introduit pour la première fois par CommonLoops, je pense)
  • OO basé sur les prédicats (aucune idée)

Et probablement d'autres que je ne connais pas.

JavaScript met en œuvre une OO basée sur des prototypes. Dans ce type d'organisation, les nouveaux objets sont créés en copiant d'autres objets (au lieu d'être instanciés à partir d'un modèle de classe) et les méthodes sont directement intégrées aux objets plutôt qu'aux classes. L'héritage se fait par délégation : si un objet ne possède pas de méthode ou de propriété, il est recherché dans son ou ses prototypes (c'est-à-dire l'objet à partir duquel il a été cloné), puis dans les prototypes du prototype et ainsi de suite.

En d'autres termes : il n'y a pas de classes.

JavaScript dispose en fait d'une belle adaptation de ce modèle : les constructeurs. Non seulement vous pouvez créer des objets en copiant des objets existants, mais vous pouvez également les construire "de toutes pièces", pour ainsi dire. Si vous appelez une fonction avec la balise new cette fonction devient un constructeur et la fonction this ne pointera pas vers l'objet actuel mais vers un objet "vide" nouvellement créé. Ainsi, vous pouvez configurer un objet comme bon vous semble. De cette façon, les constructeurs JavaScript peuvent jouer l'un des rôles des classes dans l'OO traditionnel basé sur les classes : servir de modèle ou de plan pour les nouveaux objets.

JavaScript est un langage très puissant, il est donc assez facile d'implémenter un système OO basé sur des classes. dans JavaScript si vous le souhaitez. Toutefois, vous ne devez le faire que si vous en avez vraiment besoin et pas seulement parce que c'est la façon de faire de Java.

56voto

Daniel X Moore Points 6026

Je préfère utiliser l'ouvrage de Daniel X. Moore {SUPER: SYSTEM} . Il s'agit d'une discipline qui offre des avantages tels que de véritables variables d'instance, un héritage basé sur les traits, des hiérarchies de classes et des options de configuration. L'exemple ci-dessous illustre l'utilisation de véritables variables d'instance, ce qui, à mon avis, est le plus grand avantage. Si vous n'avez pas besoin de variables d'instance et que vous vous contentez de variables publiques ou privées, il existe probablement des systèmes plus simples.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  return {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };
}

var fogel = Person({
  age: "old enough"
});
fogel.introduce(); // "Hi I'm McLovin and I'm old enough"

Wow, ce n'est pas vraiment très utile en soi, mais regardez l'ajout d'une sous-classe :

function Ninja(I) {
  I = I || {};

  Object.reverseMerge(I, {
    belt: "black"
  });

  // Ninja is a subclass of person
  return Object.extend(Person(I), {
    greetChallenger: function() {
      return "In all my " + I.age + " years as a ninja, I've never met a challenger as worthy as you...";
    }
  });
}

var resig = Ninja({name: "John Resig"});

resig.introduce(); // "Hi I'm John Resig and I'm 25"

Un autre avantage est la possibilité d'avoir des modules et un héritage basé sur les traits.

// The Bindable module
function Bindable() {

  var eventCallbacks = {};

  return {
    bind: function(event, callback) {
      eventCallbacks[event] = eventCallbacks[event] || [];

      eventCallbacks[event].push(callback);
    },

    trigger: function(event) {
      var callbacks = eventCallbacks[event];

      if(callbacks && callbacks.length) {
        var self = this;
        callbacks.forEach(function(callback) {
          callback(self);
        });
      }
    },
  };
}

Un exemple d'inclusion du module bindable dans la classe de la personne.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  var self = {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };

  // Including the Bindable module
  Object.extend(self, Bindable());

  return self;
}

var person = Person();
person.bind("eat", function() {
  alert(person.introduce() + " and I'm eating!");
});

person.trigger("eat"); // Blasts the alert!

Divulgation : Je suis Daniel X. Moore et ceci est mon {SUPER: SYSTEM} . C'est la meilleure façon de définir une classe en JavaScript.

41voto

liammclennan Points 3535
var Animal = function(options) {
    var name = options.name;
    var animal = {};

    animal.getName = function() {
        return name;
    };

    var somePrivateMethod = function() {

    };

    return animal;
};

// usage
var cat = Animal({name: 'tiger'});

24voto

Jarek Points 2092

Je pense que vous devriez lire le livre de Douglas Crockford. Héritage prototypique en JavaScript y Héritage classique en JavaScript .

Exemples tirés de sa page :

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

Effet ? Il vous permettra d'ajouter des méthodes de manière plus élégante :

function Parenizor(value) {
    this.setValue(value);
}

Parenizor.method('setValue', function (value) {
    this.value = value;
    return this;
});

Je recommande également ses vidéos : JavaScript avancé .

Vous pouvez trouver d'autres vidéos sur sa page : http://javascript.crockford.com/ Dans le livre de John Reisig, vous trouverez de nombreux exemples tirés du site Web de Douglas Crockfor.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X