原型相关(二)

1.继承

继承方式:接口继承(只继承方法签名)实现继承(继承实际的方法)
ECMAScript只支持实现继承,并且主要是依靠原型链实现。
构造函数,原型和实例的关系:每个构造函数都有个原型对象,原型对象都包含一直指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

原型链实现的基本模式:

functionn 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;
};
var instance=new SubType();
alert(instance.getSuperValue());

上面的代码定义了两个类型:SuperType和SubType,SubType继承了SuperType,通过创建一个SuperType的实例,实现的本质是重写SubType的原型对象。
1.所有函数的默认原型是Object
2.谨慎的定义方法:给原型添加的代码一定要在替换原型的语句之后

function SuperType(){
  this.property=true;
}
SuperType.prototype.getSuperValue=function(){
  return this.property;
};
function SubType(){
  this.subproperty=false;
}
SubType.prototype=new SuperType();//继承SuperType,这里SuperType的实例 替换了SubType的原型,接着再定义下面的两个方法
//添加新方法
SubType.prototype.getSubValue=function(){
  return this.subproperty;
}
//重写超类型中的方法
SubType.prototype.getSuperValue=function(){
  return false;
}
var instance1=new SubType();
alert(instance1.getSuperValue());//false
var instance2=new SuperType();
alert(instance2.getSuperValue());//true

通过原型链实现继承时,不能使用对象自变量创建原型方法

function SuperType(){
  this.property=true;
}
SuperType.prototype.getSuperValue=function(){
  return this.property;
};
function SubType(){
  this.subproperty=false;
}
SubType.prototype=new SuperType();//继承SuperType
//添加新方法
SubType.prototype={
 getSubValue:function(){
    return this.subproperty;
  },
  someOtherMethod:function(){
    return false;
  }
};

var instance1=new SubType();
alert(instance1.getSuperValue());//error

这里面,SubType和SuperType之间没有关系

2.原型链存在的问题

a.主要问题来自包含引用值类型的原型;包含引用类型值的原型属性会被所有实例共享
b.创建子类型的实例时,不能向超类型的构造函数中传递参数
具体参考原型相关(一)的原型模式的问题

function SuperType(){
  this.colors=["red","blue","gray"];
}
function SubType(){}
SubType.prototype=new SuperType();
var instance1=new SubType();
instance1.colors.push("black");
alert(instance1.colors);//"red,blue,gray,black"
var instance2=new SubType();
alert(instance2.colors);//"red,blue,gray,black"

3.因此要借用构造函数

基本思想:在子类型构造函数的内部调用超类型的构造函数

function SuperType(){
  this.colors=["red","blue","gray"];
}
function SubType(){
  SuperType.call(this);//酱紫继承了SuperType
}

var instance1=new SubType();
instance1.colors.push("black");
alert(instance1.colors);//"red,blue,gray,black"
var instance2=new SubType();
alert(instance2.colors);//"red,blue,gray"

上面的注释行,在新创建的SubType实例的环境下借调了超类型的构造函数,这样,在新SubType对象上执行SuperType()函数中定义的所有对象初始化代码,因此每个对象就会拥有寄几的colors副本啦

传递参数

function SuperType(name){
  this.name=name;
}
function SubType(){
  SuperType.call(this,"Andy");//酱紫继承了SuperType
  this.age=20;//实例属性
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容