8
votes

Est-ce un bon moyen de faire JS OOP?

Je voulais poser des questions sur les avantages de mon style OOP suivant. J'écris mes classes JS de la manière suivante.

var MyClass = function() {
    // private vars
    var self = this,
        _foo = 1,
        _bar = "test";

    // public vars
    this.cool = true;

    // private methods
    var initialize = function(a, b) {
        // initialize everything
    };

    var doSomething = function() {
        var test = 34;
        _foo = cool;
    };

    // public methods
    this.startRequest = function() {

    };

    // call the constructor
    initialize.apply(this, arguments);
};

var instance_1 = new MyClass();
var instance_2 = new MyClass("just", "testing");


0 commentaires

6 Réponses :


3
votes

1 commentaires

Notez que les Douglas ont désigné l'article «héritage classique dans JavaScript» une fois qu'il «a» le héritage prototypial



1
votes

J'ai toujours trouvé le site Web de Douglas Crockford comme une ressource inestimable pour les meilleures pratiques JavaScript. Il arrive simplement qu'il ait écrit plusieurs articles pertinents pour votre question.


0 commentaires

2
votes

En fait, cela n'est pas différent de la manière dont le prototype.js (ma bibliothèque préférée) le fait généralement. Si vous regardez ici:

var Class = (function() {
  function subclass() {};

  // All classes are created through Class.create( {/*JSON Object*/} );
  // or Class.create( function, ...properties );
  // The first form will create a unique class.
  // The second form will create a Class which subclasses the initial function.
  function create() {

    var parent = null, 
                     // $A just normalizes the array.
        properties = $A(arguments);

    // Which type of class definition was used?
    if (Object.isFunction(properties[0]))
      parent = properties.shift();

    // This effectively creates a constructor
    function klass() {
      this.initialize.apply(this, arguments);
    }

    // Allows klass to have addMethods property
    Object.extend(klass, Class.Methods);
    klass.superclass = parent;
    klass.subclasses = [];

    // Does this class have a parent class?
    if (parent) {
      subclass.prototype = parent.prototype;
      klass.prototype = new subclass;
      parent.subclasses.push(klass);
    }

    // Add methods to the class
    for (var i = 0; i < properties.length; i++)
      klass.addMethods(properties[i]);

    // emptyFunction = function(){};
    if (!klass.prototype.initialize)
      klass.prototype.initialize = Prototype.emptyFunction;

    // Creates the constructor
    klass.prototype.constructor = klass;
    return klass;
  }

  function addMethods(source) {
    // Does this class have a parent?
    var ancestor   = this.superclass && this.superclass.prototype;

    // Grab the keys of a JSON object
    var properties = Object.keys(source);

    // Makes sure each object has a toString and valueOf method.
    if (!Object.keys({ toString: true }).length) {
      if (source.toString != Object.prototype.toString)
        properties.push("toString");
      if (source.valueOf != Object.prototype.valueOf)
        properties.push("valueOf");
    }

    //Loop through the properties.
    for (var i = 0, length = properties.length; i < length; i++) {

      // property is the Key in the JSON, value is the corresponding
      // method or property value.
      var property = properties[i], value = source[property];
      if (ancestor && Object.isFunction(value) &&
          value.argumentNames().first() == "$super") {

        // Handles an override of a parent method.
        var method = value;
        value = (function(m) {
          return function() { return ancestor[m].apply(this, arguments); };
        })(property).wrap(method);

        value.valueOf = method.valueOf.bind(method);
        value.toString = method.toString.bind(method);
      }
      this.prototype[property] = value;
    }

    return this;
  }

  // And here is the final value!
  return {
    create: create,
    Methods: {
      addMethods: addMethods
    }
  };
})();


0 commentaires

6
votes

Je pense que c'est une très bonne approche. N'ayez pas honte de la question de «pas d'héritage». La plupart des OOP ne consistent pas à l'héritage. Les aspects les plus importants sont l'encapsulation et le polymorphisme, et vous les avez.

On peut soutenir (Eh bien, je discute habituellement) que l'héritage n'est nécessaire que pour les langues statiques, où vous devez en quelque sorte dire au compilateur que ces deux types (classes) sont liés, qu'ils ont quelque chose en commun (le commun ancêtre) afin qu'il puisse permettre le polymorphisme. Avec des langues dynamiques, OTOH, le compilateur ne s'en souciera pas et l'environnement d'exécution trouvera les points communs sans héritage.

Un autre point: Si vous avez besoin d'un certain héritage dans certains endroits (et c'est grand dans certains cas, comme Guis, par exemple), vous constaterez souvent que vous pouvez facilement interagir entre votre "simple «Objets / classes, et autres plus complexes et plus lourds. Iow: N'essayez pas de trouver un cadre qui remplit tous vos besoins et l'utilisez pour tout; Utilisez plutôt celui que vous êtes plus à l'aise avec à chaque instant, tant que cela aide avec le problème spécifique.


2 commentaires

+1 pour - les aspects les plus importants sont l'encapsulation et le polymorphisme.


+1 ici aussi. L'héritage est certainement donné un poids indue dans de nombreux articles sur OO. Je viens de commencer à programmer de manière productive les deux dernières années et j'ai déjà perdu le nombre de mes erreurs de Newbie causées par une héritage de dépendance.



0
votes

Si vous recherchez une structure d'héritage plus basée sur la classe dans JavaScript, vous voudrez peut-être consulter dojo .


0 commentaires

0
votes

Vous pouvez également utiliser des littéraux et des constructeurs. De cette façon, vous n'aurez pas aux concepts moins attrayants de JavaScript: prototype, nouvelle déclaration et le mot-clé.

La recette de base est simple: p>

  • créer une fonction qui construit un objet littéral li>
  • mettre cette fonction dans un objet littéral li> ul>

    Le littéral qui a le constructeur agit comme une classe. Les fonctions de constructeur agissent comme un constructeur et les actes littéraux produits comme une instance de classe. P>

    Voici un exemple: p>

    Car = {
        createNew:function() { //no prototype!
            var obj = {};
            var color;
            obj.setColor = function(c) { color = c; }
            obj.drive = function(){ alert('driving a '+color+' car'); }
            return obj; //no this-keyword!
        }
    }
    
    var car = Car.createNew(); //no new statement!
    car.setColor('red');
    car.drive();
    


0 commentaires