js的继承

82 阅读2分钟

function superType(name){
   this.name = name;
};
function subType(){
   superType.call(this, 'mary')
};

通过call的方式,将父类上的this指向改为子类的this指向,这样父类上的实例属性会被作为子类上的独一无二的实例属性,但是这样只是得到了父类上的实例属性,而还是不可### 原型链的继承

function superType(){};
function subType(){};
subType.prototype = new superType();

也就是让子类的原型指向父类构造函数的实例 这样父类上的实例属性会作为子类原型上的属性 从而会导致当我们子类去修改父类的实例属性的时候 会导致一个全部的变动,也就是说父类上的实例没有属于自己的实例属性,会随时被修改,所以这样还是不合适的

盗用构造函数继承

function superType(name){
   this.name = name;
};
function subType(){
   superType.call(this, 'mary')
};

通过call的方式,将父类上的this指向改为子类的this指向,这样父类上的实例属性会被作为子类上的独一无二的实例属性,但是这样只是得到了父类上的实例属性,而还是不可以使用父类上的原型方法等

组合式继承

function superType(){};
function subType(){
    superType.call(this, 'mary')
};
subType.prototype = new superType();

这样,结合了盗用构造函数和原型链继承的优点,,虽然,通过subType.prototype = new superType();的方式 子类还是会将父类的实例属性作为子类的原型,但是 通过 superType.call(this, 'mary')的方式 会将父类上的实例属性给变成子类上的实例属性 从而遮盖住了子类原型上继承到的父类的实例属性 但是还存在的一个缺陷就是 会调用两次父类的构造函数

原型式继承

function object(obj){
    function F(){};
    F.prototype = obj;
    return new F();
}

这样 其实和原型链的继承差不多的含义 只是这里传进去的直接是一个对象而已

寄生式继承

function object(obj){
    function F(){};
    F.prototype = obj;
    return new F();
}
function creatorObj(obj){
    let cloneObj = object(obj):
    cloneObj.sayHi = function(){
        console.log('hi');
    }
}

只不过是在原型式的继承上加一些属性而已

寄生式组合继承

function object(obj){
    function F(){};
    F.prototype = obj;
    return new F();
};
function creator(sub, super) {
    // 这样 就也避免了调用父类的构造函数 所以 这种方式 
    // 只会调用一次构造函数
     let proto = object(super.prototype);
     // 得到父类原型的代理  然后让子类的原型去指向这个代理
     sub.prototype = proto;
     sub.prototype.constrcutor = sub;
}
function superType(){};
function subType(){
    // 只是在这里调用了一次父类的构造函数
    superType.call(this); 
};
creator(subType, superType);