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

javascript学习笔记(七)---继承的实现

ECMAScript 中实现继承的方式不止一种。这是因为 JavaScript 中的继承机制并不是明确规定的,而是通过模仿实现的。这意味着所有的继承细节并非由解释程序处理。

?

对象冒充--- 构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可使 ClassA 的构造函数成为 ClassB 的方法,然后调用它。 ClassB 就会收到 ClassA 的构造函数中定义的属性和方法。

function ClassA(sColor){
	this.color = sColor;
	this.sayColor = function (){
		alert(this.color);
	}
}

function ClassB(sColor,sName){
	this.newMethod = ClassA;	//为ClassA赋予了方法newMethod
	this.newMethod(sColor);		//调用newMethod
	delete this.newMethod;		//删除对ClassA的引用

	this.name = sName;
	this.sayName = function(){
		alert(this.name);
	}
}

?

?所有的新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法.

?可以实现多继承

?

call() 方法--- 与经典的对象冒充方法相似, 第一个参数用作 this 的对象。其他参数都直接传递给函数自身。

function ClassA(sColor){
	this.color = sColor;
	this.sayColor = function (){
		alert(this.color);
	}
}

function ClassB(sColor,sName){
	ClassA.call(this,sColor);  //this让ClassA中的关键字this等于新创建的ClassB对象
						//第二个参数sColor对两个类来说都是唯一的参数。
	this.name = sName;
	this.sayName = function(){
		alert(this.name);
	}
}
?

apply() 方法--- 与call()相似,两个参数,用作 this 的对象和要传递给函数的参数的数组。

function ClassA(sColor){
	this.color = sColor;
	this.sayColor = function (){
		alert(this.color);
	}
}

function ClassB(sColor,sName){
	ClassA.apply(this,arguments);//只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象
	ClassA.apply(this,new Array(sColor));//如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。

	this.name = sName;
	this.sayName = function(){
		alert(this.name);
	}
}

?

原型链--- 用另一类型的对象重写类的 prototype 属性。

prototype 对象的任何属性和方法都被传递给那个类的所有实例。 子类的所有属性和方法都必须出现在 prototype 属性被赋值后,因为在它之前赋值的所有方法都会被删除。

缺点:使用原型链,就无法使用带参构造函数了

function ClassA(){
}

ClassA.prototype.name = "nomad";
ClassA.prototype.sayName = function(){
	alert(this.name);
}

function ClassB()
}
ClassB.prototype = new ClassA(); //要确保调用构造函数没有任何参数。

ClassB.prototype.age = 23;
ClassB.prototype.sayAge = function(){
	alert(this.age);
}
?

混合方式--- 对象冒充继承构造函数的属性,用原型链继承 prototype 对象的方法。

function ClassA(aName){
	this.name = aName;
}

ClassA.prototype.sayName = function(){
	alert(this.name);
}

function ClassB(aName,aAge){
	ClassA.call(this,aName);
}

ClassB.prototype = new ClassA();

ClassB.prototype.sayAge = function(){
	alert(this.age);
}
?

其他继承方式:

zInherit