1.原型链继承:
function Parent(){
this.name = "parent";
this.say = function(){
console.log(this.name);
}
}
// 定义子类
function Child(){
this.name = "child";
}
Child.prototype = new Parent(); // 将子类的原型对象指向父类的实例
Child.prototype.construce = Child; // 修复constructor使符合原型链规定
var child = new Child(); // 实例化子类
child.say(); // child // 此时子类能够访问父类的say方法,在查找name属性的时候首先在自身属性中查找成功所以不再向上查找,若子类没有name成员,则会打印parent
console.log(child instanceof Parent); // true // 判断child的构造函数Child的prototype对象是否在Parent的原型链上
总结:共享父类原型对象属性
- 不足:修改原型对象属性会影响其他子类,不能向父类原型传参
构造函数继承
// 定义父类
function Parent(from){
this.name = "parent";
this.say = function(){
console.log(this.name);
}
this.from = from;
}
// 定义子类
function Child(from){
Parent.call(this, from); // 调用父类构造函数并绑定this来拓展Child实例成员方法,可以传递参数
this.name = "child";
}
var child = new Child("child"); // 实例化子类
child.say(); // child
console.log(child.from); // child
总结:继承了构造函数构造函数,子类属性互不影响,修复了原型链的不足。
- 无法继承父类原型对象属性
组合式继承
function Parent(from){
this.name = "parent";
this.say = function(){
console.log(this.name);
}
this.from = from;
}
// 定义子类
function Child(from){
Parent.call(this, from);//调用一次
this.name = "child";
}
Child.prototype = new Parent();//调用二次
Child.prototype.construce = Child;
var child = new Child("child"); // 实例化子类
child.say(); // child
console.log(child.from); // child
总结:结合了两种模式的优点,传参和复用
- 多次调用Parent
寄生组合式继承
function Parent(from){
this.name = "parent";
this.say = function(){
console.log(this.name);
}
this.from = from;
}
// 定义子类
function Child(from){
Parent.call(this, from);
this.name = "child";
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.construce = Child;
var child = new Child("child"); // 实例化子类
child.say(); // child
console.log(child.from); // child
几个相关小点
- object.create其实就是原型式继承(Object.create(proto,[propertiesObject]))
- 内置的函数对象Funtion的原型prototype是Object的实例,但却是function类型