2009-08-11 106 views
8

我想问一下我的以下OOP风格的优点。 我以下面的方式编写我的JS类。这是做JS OOP的好方法吗?

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

我认为这是一个非常好的方法。不要为'不传承'问题感到羞耻。大多数面向对象不是关于继承。最重要的方面是封装和多态,你已经得到了它们。 (可以,我经常说)只有静态语言需要继承,你必须告诉编译器这两种类型(类)是相关的,他们有一些共同的东西(共同的祖先),以便它可以允许多态性。使用动态语言OTOH,编译器不会在意,运行时环境将找到没有任何继承的共同点。另一点:如果您在某些地方需要继承(例如,在某些情况下,它的编号为,那么例如像GUI一样),但通常您会发现可以轻松地在“简单”对象/类之间进行互操作,其他更复杂和更重。 IOW:不要试图找到满足您所有需求并将其用于一切的框架;而是使用你在任何时刻都更加适应的方法,只要它能帮助解决特定的问题。

+0

+1 - 最重要的方面是封装和多态性。 – Everyone 2009-08-13 09:09:04

+0

也在这里。在面向对象的许多文章中,继承肯定是过分的重量。在过去的几年中,我刚刚开始有成效地开展OO编程,并且我已经失去了因过度依赖继承而导致的新手错误的数量。 – 2011-07-11 01:57:45

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

上面的好处是,你将能够快速,轻松地管理继承。在你的情况下,如果不像上面那样创建某种形式的外部帮助函数,继承(或至少重写函数)几乎是不可能的。

0

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

0

你也可以使用文字和建设者。通过这种方式,您不必在Javascript中使用不太吸引人的概念:原型,新语句和this关键字。

的基本配方很简单:

  • 创建生成一个文本对象
  • 提出,在一个文本对象

字面具有建设者作为一类功能的功能。构建器函数充当构造函数,并且生成的文字充当类实例。

下面是一个例子:

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