手写JS继承


// 通过原型链实现继承的关键点是
Child.prototype = new Parent();
// 不同的Child实例的__proto__会引用同一个Parent的实例

// 构造函数实现继承:
function Child(args) {
    //...
    Parent.call(this, args);
}
// 只实现了实例属性继承,Parent原型的方法在Child实例上不可用

// 组合继承
// Parent原型的方法在Child实例上可用
function Child(arg1, arg2) {
    //...
    this.args2 = arg2;
    Parent.call(this, arg1); // 第一遍
}
Child.prototype = new Parent(); // 此处构造函数会调用两遍, 第二遍,不好
Child.prototype.contructor = Child; // 在上一句话中Child的原型全部都指向了Parent的实例,所以这时的Child的contructor为Parent,所以需要重新赋值回来正确的Child

// 寄生组合式继承(常用)
function Parent(name) {
    this.name = name;
}
Parent.prototype.sayName = function () {
    console.log(this.name);
};

function Child(name) {
    Parent.call(this, name);
    this.name = name;
}
Child.prototype = Object.create(Parent.prototype);
Child.contructor = Child;

// 集成为函数写法
function inherit(Child, Parent) {
    // 继承原型上的属性
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.contructor = Child;

    // 存储超类
    Child.super = Parent;

    // 拷贝静态属性和静态方法(指原型上的方法和属性)
    if (Object.setPrototypeOf) {
        Object.setPrototypeOf(Child, Parent);
    } else if (Child.__proto__) {
        Child.__proto__ = Parent;
    } else {
        for (var prop in Parent) {
            if (Parent.hasOwnProperty(prop) && !(prop in Child)) {
                Child[prop] = Parent[k];
            }
        }
    }
}

function inherit(Child, Parent) {
    function Superfn() {}
    Superfn.prototype = Parent.prototype;
    const prototype = new Superfn();
    prototype.constructor = Child;
    Child.prototype = prototype;
}

// es6 继承

class Child extends Parent {
    constructor(name, age) {
        super(name);
        this.age = age;
    }
}
© 2024 Hogan Hu