es5的一些继承

87 阅读1分钟

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类型