[翻译文章,原文来自:http://www.yuiblog.com/blog/2010/01/06/inheritance-patterns-in-yui-3/]

这篇文章讨论YUI 3 中实现的两种JavaScript代码重用模式――类型继承模式(classical inheritance pattern)和原型继承模式(prototypal inheritance pattern)。

需要的依赖(satisfied dependences)

原型继承模式作为YUI 3 核心API在”yui-min.js”种子文件中实现的。类型继承模式则需要”oop”模块。但是因为”oop”模块会被很多别的模块所使用,一般来说你不需要做额外引用来使用这个功能。如果你想自己创建一个简单的测试页面来试试这个模式,可以如下引用需要的模块

类型继承模式(classical inheritance pattern)

我们称类型继承模式为”经典模式”(classical)并不是因为它来自古埃及的柏拉图时代,而是因为这种模式可以帮助你以”类型”的方式思考问题。JavaScript没有类型,取而代之的是它有构造函数(constructor)。例如在Java或者其他语言中你可以定义”Programmer”类型并让它继承”Person”类型。但是,JavaScript中你能直接定义的是一个Programmer构造函数和一个Person构造函数。类型继承模式的目标就是让Programmer构造函数创建出来的对象可以继承由Person构造函数创建的属性 (properties) 和方法 (methods) 。

考虑下面两个构造函数:

YUI 3中”oop”模块提供的”Y.extend(…)”方法能让你非常容易地实现类型继承模式:

现在你就可以如下测试”getName()”方法是否被正确继承下来:

注意”Y.extend(…)”方法只继承prototype中的成员,而不包括私有成员(“own” members)。所以,一个好的习惯就是把所有可重用的功能添加到prototype中,并且把所有和类型实例相关的属性定义为私有属性(“own” properties)。如上面例子,”getName()”被继承到Programmer中,而”name”则没有被继承(在后面要讨论到的原型继承模式中,”prototype”成员和”own”成员都会被继承)。

扩展与增强(extend and augment)

“Y.extend(…)”函数不仅可以让你继承父构造函数,同时还可以给子类添加新的成员。YUI这种用来扩展类的方式其实就是”de facto“模式。你可以利用”Y.extend(…)”函数的第三个参数在子类的”prototype”中添加属性,并且你可以用它的第四个参数给子类添加它自己的静态属性(class static properties)。下面就是一个扩展与增强的例子:

父类(superclass)

YUI3的类型继承模式还提供了一个静态属性――superclass—让你访问父类构造函数的prototype。因为”supperclass”指向父类构造函数的prototype,所以”superclass.custructor”就指向父类的构造函数。如下列:

如前所说,经典继承模式只能继承prototype成员。但是通过使用”superclass”,你可以在子类中调用父类的构造器。这样你就把父类的私有属性(own properties)变成子类的私有属性(own properties)。例如,你可以在Programmer构造器中调用父类构造器,传入子类实例(this)和任何初始化参数:

如例所见,”Programmer”实例现在就有”name”属性,并且它是一个私有属性(own property):

访问重置方法(access to overridden methods)

因为”superclass”指向父类构造函数的prototype,这给我们提供了一个访问重置方法的途径。考虑下面这个经典例子(Triangle继承自Shape):

原型继承模式(Prototypal inheritance pattern)

Douglas Crockford 推荐这种继承模式。该模式剔除所有类型的概念,让你直接从一个实例继承出另外一个实例。例如:

你通过下面两步来使用这个模式:

  1. 创建一个新的对象,它继承一个已存在对象的所有属性和方法。
  2. 扩展(customize)这个新的对象――你可以覆盖一些继承来的成员或者添加新的成员。

注意:”Y.Object(…)”包含在YUI核心库中。你不需要应用”oop”模块

原型继承讨论

如果你对原型继承模式后面动机和低层实现机制感兴趣,可以参考Douglas Crockford他自己对这个模式的描述。使用这个模式时,父类的成员通过”prototype”链继承下来的。这就意味着如果子类添加了一个与父类同名的属性,子类属性不会覆盖从父类继承来的那个属性,但是它会拥有优先访问权。换句话说,你可以如下重新定义上面例子中的”say”方法:

与Y.extend(…)函数提供的类型继承模式所不同,原型继承模式无法提供类似与”superclass”属性来访问父类的”say”方法。但是,如果你删除(delete)子类的”say”方法后,父类的方法就露出来。如下:

ECMAScript标准最新版本中,它提供一个native方法”Object.create(…)”来支持原型继承模式:

更多资源

谢谢你的阅读!关于这两个模式的更多信息和例子,你可以参考下面的链接:

  • Todd Kloots\' "YUI 3 Sugar" presentation
    
  • oop模块API文档  
    
  • oop模块源代码    
    
  • extend方法的例子    
    
  • Y.Object方面的源代码  
    

Del.icio.us : YUI 3, 代码重用模式, 继承模式

版权声明:本文为xuguilin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xuguilin/archive/2010/04/03/1703546.html