一、原型链进行继承
1.JS的继承主要依靠原型链来实现,使函数的原型指向另一函数的实例,依次来完成继承,其实质就是重写原型对象。
继承后属性和方法的依照原型链进行搜索,1)先在实例中搜索,2)搜索SubType.prototype,3)搜索SuperType.prototype,直到找到该方法或者该属性。
所有函数的默认原型是Object实例。
2.确认原型和实例的关系
instanceof操作符和isPrototypeOf()方法
3.例子:原型的定义与方法的重写,一定要先定义原型,再给原型添加或者重写方法,这与先指定原型再创建对象是一样的道理,否则方法中存在的指向原先原型的指针会失效,导致调用方法失败(undefined)。
<script type="text/javascript">
window.οnlοad=function(){
var inputEles=document.getElementsByTagName("input");
inputEles.item(0).οnclick=function(){
function SuperType(){
this.property=true;
};
SuperType.prototype.getSuperValue=function(){
return this.property;
};
function SubType(){
this.subProperty=false;
};
//先定义原型,然后往原型中添加方法或者重写父类中的方法
SubType.prototype=new SuperType();
SubType.prototype.getSubValue=function(){
return this.subProperty;
};
SubType.prototype.getSuperValue=function(){
return false;
};
var sub=new SubType();
alert(sub.getSuperValue());
};
};
</script>
4.原型链在继承所面临的问题:如果原型中的某一属性为引用类型,则通过实例对该属性的修改将会影响到所有该类型的实例。
inputEles.item(1).οnclick=function(){
function SupType(){
//申明属性
this.colors=["red","green","yellow"];
};
SubType.prototype.getColors=function(){
return this.colors;
};
function SubType(){};
//继承
SubType.prototype=new SupType();
var instance1=new SubType();
instance1.colors.push("black");//"red","green","yellow","black"
alert(instance1.colors);
var instance2=new SubType();
alert(instance2.colors);//"red","green","yellow","black"
};
原型继承的第二个问题是不能想他所继承的父类中传参,无法自定义的构造其父类。
二、借用构造函数进行继承
<span style="white-space:pre"> </span>inputEles.item(2).οnclick=function(){
function SupType(name){
this.name=name;
};
function SubType(name,age){
//调用构造器进行继承
SupType.call(this, name);
this.age=age;
};
var instance1=new SubType("Nicholas",24);
alert(instance1.name+","+instance1.age);
};
但是调用构造器进行继承面临的问题同样很明显,每个实例中方法都是不同的,方法的复用无从谈起。
三、组合继承:
JS的继承中,一般属性使用构造器进行继承,而方法则通过原型链进行继承。
对于构造亦是同理。
inputEles.item(3).οnclick=function(){
function SupType(name){
this.name=name;
this.colors=["red","green","yellow"];
};
SupType.prototype.sayName=function(){
alert(this.name);
};
//属性的继承
function SubType(name,age){
SupType.call(this, name);
this.age=age;
};
//方法的继承要采用原型链
//首先重写原型,指明属性采用原型链进行构造
SubType.prototype=new SupType();
SubType.prototype.constructor=SubType;
var instance1=new SubType();
var instance2=new SubType();
alert("两个实例对象中的方法是否为同一个方法:"+(instance1.sayName==instance2.sayName));//true
instance1.colors.push("black");
alert(instance1.colors);//"red","green","yellow","black"
alert(instance2.colors);//"red","green","yellow"
};