您的位置:首页 > Web前端 > JavaScript

javascript继承学习系列之二:原型链(Prototype Chaining)

2011-07-06 13:27 357 查看
原型链是采用的最主要的继承方式,它的思路是这样的:每一个类(构造器,js中的function)都有一个原型属性(prototype)指向原型对象,原型对象有一个构造器属性(constructor),它又指回到function,是个循环引用。类的每个实例,也有个原型属性(代码无法访问的,
叫做__proto__),它跟构造器原型指向的是同一个对象,即同一个类的所有实例共用一个原型对象。要实现两个类型的继承,就是将一个类型的原型指向另一个类型的实例,而不在指向原来的默认的原型对象。这样就形成了原型链。

子类可以通过原型链获得超类的所有属性和方法。从而实现了继承。基本的js代码如下:

//supper class

function BaseClass()

{

this.baseName="BaseClass";

}

BaseClass.prototype.getBaseClassName = function(){return this.baseName;}

//child class

function ChildClass

{

this.childName="ChildClass";

}

//make prototype chaining, inherit

ChildClass.prototype = new BaseClass();

ChildClass.prototype.getChildClassName = function(){return this.childName;}

var instance = new ChildClass();

alert(instance.getBaseClassName ());//BaseClass

ChildClass(及它的实例)的prototype(__proto__)属性不再指向默认的prototype对象,而是BaseClass的
实例,这个实例也有个属性(__proto__),它指向的是BaseClass的原型对象。在ChildClass的实例instance上查找
baseName属性的过程是这样的:首先,在实例instance自身上找baseName属性,没有找到,则在它的原型对象(__proto__属
性,此时是BaseClass的实例,不在是默认的原型对象)上查找,并找到baseName属性,返回它的值;而getBaseClassName()
方法的查找,首先是在instance自身上,但并没找到,然后进入的它的原型对象(__proto__属性,此时是BaseClass的实例,不在是默
认的原型对象)上,依然没找到,则进入这个BaseClass的实例的原型对象(__proto__属性,默认的原型对象)上找,终于找到,则返回这个方
法的执行结果。

像文中强调的那样,类型的原型对象是其所有实例所共有的,这就造成了这样一个问题:原型对象(父类实例)的属性及方法的改变将影响到所有实例,无论是已经创建的还是即将创建的。分析以下代码:

function BaseClass()

{

this.colors = ["red","blue"];

}

function ChildClass()

{

}

ChildClass.prototype = new BaseClass();

var instance1 = new ChildClass();

//在此实例上对从父类继承过的属性值进行了修改。

var instance2 = new ChildClass();

instance2.colors.push("green");

var instance3 = new ChildClass();

///查看各个实例的colors属性值

alert(instance1.colors);//red,blue,green

alert(instance2.colors);//red,blue,green

alert(instance3.colors);//red,blue,green

可见对于任一个实例来讲,如果修改了它继承的属性值,则将影响到其他任何时候创建的实例。

另外,如果继承的层次过多,则对最顶层父类中的属性、方法的调用效率最低(推测,没有证实)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: