javasript是基于prototype对象实现,继承的要点如下:
1. 构造函数会存放"私有数据"--对实例而言。
2. 函数的原型prototype对象会存放"公有"数据及函数
3. 在子类的构造函数里面,调用 父类的构造方法--使用call(this)的形式,并定义自己的数据
4. 设置子类的原型prototype对象指向一个父类的实例(或者是一个空函数的实例,该空函数的prototype指向父类的prototype对象),从而可以访问到父类的原型里面的"公有"数据及函数。
可以看到,1.实例之间拥有独立的从父类继承的属性,2.实例之间拥有共同的父类方法。上述代码的一个关键就是 SubType.prototype = new SuperType();
最终“类图”如下:
[img]http://dl.iteye.com/upload/attachment/263069/1460786f-98ea-345f-957a-05b4fe523159.jpg[/img]
上面要点4括号里提到了另外一种继承方式(本质其实一样),先来看看一个函数:
可以看到,object方法实现的就是创建一个函数(F)的实例,该函数的prototype指向某一个对象,返回的函数(F)的实例,
从而,实际上效果就是:返回的实例是入参的“子类”。
其“类图”如下:
[img]http://dl.iteye.com/upload/attachment/263073/500ea491-33a1-3e73-8693-15ff52f86579.jpg[/img]
有了上面对object函数的分析,我们可以用第二种形式实现继承:
整理自《Professional.JavaScript.for.Web.Developers.2nd.Edition》
1. 构造函数会存放"私有数据"--对实例而言。
2. 函数的原型prototype对象会存放"公有"数据及函数
3. 在子类的构造函数里面,调用 父类的构造方法--使用call(this)的形式,并定义自己的数据
4. 设置子类的原型prototype对象指向一个父类的实例(或者是一个空函数的实例,该空函数的prototype指向父类的prototype对象),从而可以访问到父类的原型里面的"公有"数据及函数。
function SuperType(name){
this.name = name;
this.colors = ['red','green','blue'];
};
SuperType.prototype.getName = function(){
return this.name;
}
function SubType(name,age){
//继承所有属性
SuperType.call(this,name);
this.age = age;
}
//继承父类的方法
SubType.prototype = new SuperType();
//修复constructor的指向
SubType.prototype.constructor = SubType;
SubType.prototype.getAge = function(){
return this.age;
}
var s1 = new SubType('Tom',10);
alert(s1.getName());
alert(s1.getAge());
alert(s1.getColor());
s1.color.push('black');
var s2 = new SubType('Jerry',8);
alert(s2.color);
//函数prototype上的属性都是共有
alert(s1.getAge === s2.getAge);//true
alert(s1 instanceof SubType);//true
alert(s1 instanceof SuperType)//true
alert(s1.constructor == SubType)//ture
alert(s1.constructor == SuperType);//false
alert(s1.getName === s2.getName);//true
可以看到,1.实例之间拥有独立的从父类继承的属性,2.实例之间拥有共同的父类方法。上述代码的一个关键就是 SubType.prototype = new SuperType();
最终“类图”如下:
[img]http://dl.iteye.com/upload/attachment/263069/1460786f-98ea-345f-957a-05b4fe523159.jpg[/img]
上面要点4括号里提到了另外一种继承方式(本质其实一样),先来看看一个函数:
function object(o){
function F(){}
F.prototype = o;
return new F();
}
//使用示例
//引用类型的属性将被共享
var person = {
name: 'Tomy',
friends:['1','3','4']
}
var p2 = object(person);
p2.name = 'Jack';
p2.friends.push([5,6]);
alert(p2.friends);//1,3,4,5,6
var p1 = object(person);
alert(p1.name)//Tomy
alert(p1.friends);//1,3,4,5,6
可以看到,object方法实现的就是创建一个函数(F)的实例,该函数的prototype指向某一个对象,返回的函数(F)的实例,
从而,实际上效果就是:返回的实例是入参的“子类”。
其“类图”如下:
[img]http://dl.iteye.com/upload/attachment/263073/500ea491-33a1-3e73-8693-15ff52f86579.jpg[/img]
有了上面对object函数的分析,我们可以用第二种形式实现继承:
function inheritPrototype(subType,superType){
var prototype = object(superType.prototype);
prototype.constructror = subType;
subType.prototype = prototype;
}
举例:
function SuperType(name){
this.name = name;
this.colors = ['red','green','blue'];
};
SuperType.prototype.getName = function(){
return this.name;
}
function SubType(name,age){
//继承所有属性
SuperType.call(this,name);
this.age = age;
}
//继承父类的方法
inheritPrototype(subType,superType);
//子类共有方法
SubType.prototype.getAge = function(){
return this.age;
}
整理自《Professional.JavaScript.for.Web.Developers.2nd.Edition》