日期:2014-05-16  浏览次数:20418 次

实现JavaScript继承
javasript是基于prototype对象实现,继承的要点如下:
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();
最终“类图”如下:



上面要点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)的实例,
从而,实际上效果就是:返回的实例是入参的“子类”。
其“类图”如下:



有了上面对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》