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
可见对于任一个实例来讲,如果修改了它继承的属性值,则将影响到其他任何时候创建的实例。
另外,如果继承的层次过多,则对最顶层父类中的属性、方法的调用效率最低(推测,没有证实)。
叫做__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
可见对于任一个实例来讲,如果修改了它继承的属性值,则将影响到其他任何时候创建的实例。
另外,如果继承的层次过多,则对最顶层父类中的属性、方法的调用效率最低(推测,没有证实)。
相关文章推荐
- JavaScript中的原型继承基础学习教程
- JS学习笔记——JavaScript继承的6种方法(原型链、借用构造函数、组合、原型式、寄生式、寄生组合式)
- JavaScript学习3:原型和继承
- JavaScript学习系列之深入原型链与继承的实现
- 【转载】Javascript原型继承-学习笔记
- JavaScript学习笔记-原型继承
- Javascript学习---原型继承
- JavaScript难点系列(六):原型链与继承
- javascript基础学习三:原型继承
- 征服JavaScript面试系列:类继承和原型继承的区别
- JavaScript学习3:原型和继承
- Javascript基础系列16:Javascript的原型链和继承详解
- javascript之对象学习笔记(二)--对象原型,继承
- javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式
- javascript继承学习系列之一:初识JS的OOP
- javascript继承学习系列之三:对象伪装(Object Masquerading)
- 一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)
- javascript继承学习系列之四:组合继承(Combination Inheritance)
- 栋栋晓13:Javascript学习总结:原型、原型链和继承。
- JavaScript学习—原型和继承