首页 » 编写高质量代码:改善JavaScript程序的188个建议 » 编写高质量代码:改善JavaScript程序的188个建议全文在线阅读

《编写高质量代码:改善JavaScript程序的188个建议》建议92:不建议使用原型继承

关灯直达底部

原型继承是一种简化的继承机制,也是目前最流行的一种JavaScript继承方式。实际上JavaScript就是一种基于原型的语言。在原型继承中,类和实例概念被淡化了,一切都从对象的角度来考虑。

但是,原型继承就不再需要使用类来定义对象的结构,直接定义对象,该对象被其他对象引用,这样就形成了一种继承关系,其中引用对象称为原型对象(prototype object)。JavaScript能够根据原型链来查找对象之间的这种继承关系。下面就是一个简单的原型继承示例:


function A(x){//A类

this.x1=x;

this.get1=function{

return this.x1;

}

}

function B(x){//B类

this.x2=x;

this.get2=function{

return this.x2+this.x2;

};

}

B.prototype=new A(1);//用原型对象继承A的实例

function C(x){//C类

this.x3=x;

this.get3=function{

return this.x2*this.x2;

};

}

C.prototype=new B(2);//用原型对象继承B的实例


在上面示例中,分别定义了3个函数,然后通过原型继承方法把它们连在一起,这样C能够继承B和A的成员,B能够继承A的成员。prototype的最大特点就是能够允许对象实例共享原型对象的成员。因此,如果把某个对象作为一个类型的原型,那么就可以说这个类型的实例以这个对象为原型。实际上此时这个对象的类型也可以作为那些以这个对象为原型的实例的类型。此时,可以在C的实例中调用B和A的成员:


var b=new B(2);

var c=new C(3);

alert(b.x1);//在实例对象b中调用A的属性x1,返回1

alert(c.x1);//在实例对象c中调用A的属性x1,返回1

alert(c.get3);//在实例对象c中调用C的方法get3,返回9

alert(c.get2);//在实例对象c中调用B的方法get2,返回4


基于原型的编程是面向对象编程的一种特定形式。在这种编程模型中,不需要声明静态类,而可以通过复制已经存在的原型对象来实现继承关系。因此,基于原型的模型没有类的概念,原型继承中的类仅是一种模拟。原型继承非常简单,其优点是结构简单,不需要每次构造函数都调用父类的构造函数,并且不需要通过复制属性的方式就能快速地实现继承。但它也存在以下几个缺点:

❑由于每个类型只有一个原型,因此它不直接支持多重继承。

❑不能很好地支持多参数或动态参数的父类。在原型继承阶段,用户还不能决定以什么参数来实例化构造函数。

❑使用不够灵活。用户需要在原型声明阶段实例化父类对象,并且把它作为当前类型的原型,这会限制父类实例化的灵活性,很多时候无法确定父类对象实例化的时机和场合。