2007年3月14日

在JavaScript实现基于原型的继承

5年前我写了在JavaScript中实现基于类模式的继承。它显示了JavaScript是基于像类一样,原型的语言(class-free, prototypal)。并且它有足够的能力去模仿一个“类”似的结构,我的程序样式在那之后进行了发展,就像是任何好的程序员应当的那样。我已经完全拥护“原型主义”,并且把我从“类”的模式中解放出来。

我的旅程是迂回的,因为JavaScript它本身对于它原型的天性也相抵触。在一个原型的系统里,对象继承于对象。JavaScript尽管它缺乏一个完成那些运算的操作符,但是它有new操作符,比如:

new f()

产生一个新的对象,它继承于

f.prototype

这间接并有意地使这门语言看似可以与那些古典的训练程序员的方式一样,但是未必如此,就像我们可以看到Java程序员一直持有JavaScript是非常浅显的观点一样。JavaScript的构造器模式没有出现古典派的一伙当中,这使JavaScript是真正的天性的原型语言变得模糊不清,结果是,几乎没有知道如何有效地使用这门语言的程序员了。

幸运的是,很容易创建一个实现原型继承的操作符工具,它在我的工具包里有标准的特点,我也很高兴推荐你使用它。

    function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
    }

object函数分解了JavaScript的构造器模式,真正地达到了原型继承。它把一个旧的对象作为参数,并且返回了新的空的并继承了旧的对象的对象。当我们试图获取这个新对象的成员的时候,当它本身没有这个成员的时候,旧的对象将会提供这个成员。对象从对象继承了,很多对象如此导向会如何呢?

代替创建类,你该使用原型对象,并且使用object函数创建新的实例。在JavaScript中对象是可变的,所以我们可以扩充新的实例,给他们新的属性和方法,这些新实例又可以担当更新的实例的原型。我们不需要类去做一些相似的对象。

便于使用,我们可以创建一个叫做object函数,并且提供其它的用户化定制,比如扩充对象使用特权方法。我不时地叫他们为缔造函数,如果我们要一个缔造函数来调用另一个缔造函数来代替调用object函数,那样我们就有了parasitic继承的模式了。

我发现用这些工具,外加上JavaScript的lambdas和对象的quasi-literals,我可以写一个很好的结构化的程序,它可以是庞大的、复杂的和高效率的。古典的对象模型今天最流行的方式渐行渐远,但我认为基于原型的对象模型是更有前途和提供更丰富的表现力。

学习这些新的模式也更使我成为一个更好的古典式的程序员,以不变应万变。

特别声明,文章翻译于 Prototypal Inheritance in JavaScript
版权由原作者所有。

没有评论: