admin管理员组

文章数量:1355658

I wanted to ask about the pros cons of my the following OOP style. I write my JS classes in the following manner.

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");

Is this a good approach? Is there any drawback? I don't use inheritance, but would it work this way to achieve inheritance?

Thanks in advance.

I wanted to ask about the pros cons of my the following OOP style. I write my JS classes in the following manner.

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");

Is this a good approach? Is there any drawback? I don't use inheritance, but would it work this way to achieve inheritance?

Thanks in advance.

Share Improve this question edited Aug 15, 2009 at 17:46 Janusz 190k115 gold badges304 silver badges373 bronze badges asked Aug 11, 2009 at 21:42 fphilipefphilipe 10.1k1 gold badge41 silver badges54 bronze badges
Add a ment  | 

6 Answers 6

Reset to default 6

I think it's a very good approach. Don't be ashamed of the 'no inheritance' issue. Most OOP isn't about inheritance. The most important aspects are the encapsulation and polymorphism, and you've got them.

It can be argued (well, i usually argue) that inheritance is only needed for static languages, where you have to somehow tell the piler that these two types (classes) are related, that they have something in mon (the mon ancestor) so that it can allow polymorphism. With dynamic languages, OTOH, the piler won't care, and the runtime environment will find the monalities without any inheritance.

Another point: if you need some inheritance in some places (and it's great in some cases, like GUIs, for example), often you'll find that you can easily interoperate between your 'simple' objects/classes, and other more plex and heavier. IOW: don't try to find a framework that fills all your needs and use it for everything; instead use the one that you're more fortable with at each moment, as long as it helps with the specific problem.

I found those articles by Douglas Crockford very informative:

  • The World's Most Misunderstood Programming Language
  • Private Members in JavaScript
  • Classical Inheritance in JavaScript

Actually, that not dissimilar from the way that Prototype.js (my favorite library) generally does it. If you look here:

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
    }
  };
})();

The benefit of above is that you'll be able to manage inheritance quickly and easily. In your case inheritance (or, at least, overriding functions) is almost impossible without creating some form of external helper function like above.

I've always found Douglas Crockford's Web site to be an invaluable resource for JavaScript best-practices. It just so happens that he's written several articles pertinent to your question.

  • Private Members in JavaScript
  • Classical Inheritance in JavaScript (Hint: There is none, although you could use this approach to mimic it.)
  • Prototypal Inheritance (Follow-up to above article.)

If you're looking for a more class based inheritance structure within JavaScript you might want to check out Dojo.

You can also just use literals and builders. This way you don't have to the less attractive concepts in Javascript: prototype, new-statement and the this-keyword.

The basic recipe is simple:

  • Create a function that builds a literal object
  • Put that function in a literal object

The literal that has the builder acts as a class. The builder functions acts as a constructor and the produced literal acts as a class instance.

Here is an example:

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();

More docs can be found here:

http://www.gabordemooij./jsoop.html

and here

https://github./schuttelaar/Rococo2/wiki/Getting-started

本文标签: javascriptIs this a good way to do JS OOPStack Overflow