这是一个做JS OOP的好方法吗?

时间:2009-08-11 21:42:20

标签: javascript oop

我想问一下以下OOP风格的优点。 我用以下方式编写JS类。

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

这是一个好方法吗?有什么缺点吗? 我不使用继承,但它会以这种方式实现继承吗?

提前致谢。

6 个答案:

答案 0 :(得分:6)

我认为这是一个非常好的方法。不要为“无遗产”问题感到羞耻。大多数OOP不是关于继承。最重要的方面是封装和多态,你已经得到了它们。

可以说(好吧,我通常认为)继承只需要静态语言,你必须以某种方式告诉编译器这两种类型(类)是相关的,它们有一些共同点(共同的)祖先)这样它就可以允许多态性。使用动态语言OTOH,编译器不关心,运行时环境将找到没有任何继承的共性。

另一点:如果你在某些地方需要一些继承(例如在某些情况下很好,比如GUI),通常你会发现你可以轻松地在你的'简单之间进行互操作'对象/类,以及其他更复杂和更重的。 IOW:不要试图找到满足您所有需求的框架并将其用于一切;相反,只要它有助于解决具体问题,就可以使用你在每个时刻都更舒服的那个。

答案 1 :(得分:3)

答案 2 :(得分:2)

实际上,这与Prototype.js(我最喜欢的库)通常做的方式并没有什么不同。如果你看这里:

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

上述优点是您可以快速轻松地管理继承。在你的情况下,如果没有像上面那样创建某种形式的外部帮助函数,继承(或者至少是覆盖函数)几乎是不可能的。

答案 3 :(得分:1)

我总是发现Douglas Crockford的网站是JavaScript最佳实践的宝贵资源。碰巧他写了几篇与你的问题有关的文章。

答案 4 :(得分:0)

如果您在JavaScript中寻找更基于类的继承结构,可能需要查看Dojo

答案 5 :(得分:0)

您也可以使用文字和构建器。这样你就不必使用Javascript中那些不太吸引人的概念:prototype,new-statement和this-keyword。

基本配方很简单:

  • 创建一个构建文字对象的函数
  • 将该函数放入文字对象

具有构建器的文字充当类。构建器函数充当构造函数,生成的文字充当类实例。

以下是一个例子:

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

可在此处找到更多文档:

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

在这里

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