Cuuube / blog

blog on Mirror
1 stars 0 forks source link

[装饰器][纯代码]ts装饰器玩继承 #55

Open Cuuube opened 6 years ago

Cuuube commented 6 years ago

//////////////////warning///////////////// 以下文字含有:草稿、混乱、精神污染、不负责任、无排版、胡言乱语、抄袭等,珍爱生命者请自行决定是否右上角 //////////////////////////////////////////////

const extend = (Parent: any, options?: any) => {
    return (constructor) => {
        // ---------------第一种方法-----------------
        // 根据原型链继承原则,子类的prototype指向父类的一个实例,创建该父类实例
        var extendTarget = new Parent(options);

        // 将子类方法放入自己(要继承的实例中,即是)prototype中
        for (var i in constructor.prototype) {
            if ((i !== '__proto__') && (i !== 'constructor')) {
                extendTarget[i] = constructor.prototype[i];
            }
        }

        // 将子类的constructor.prototype指向该实例
        constructor.prototype = extendTarget;

        // -------第二种方式,其实一样,只是顺序不同---------
    /*
        // 将子类的方法覆盖到父类(注:很可能会污染父类)
        for (var i in constructor.prototype) {
            if ((i !== '__proto__') && (i !== 'constructor')) {
                Parent.prototype[i] = constructor.prototype[i];
            }
        }

        // 将子类的constructor.prototype指向父类实例
        constructor.prototype = new Parent(options);
    */
    }
}

class Animal {
    name: string;
    constructor (options) {
        this.name = options.name;
        this.init();
    }

    init() {
        console.log('Animal init!');
    }

    say (): void {
        console.log('Animal say');
    }

    sayName (): void {
        console.log(this.name);
    }

}

@extend(Animal, {
    name: '蓝皮鼠'
})
class Cat {
    name: string;
    constructor () {
        this.name = '大脸猫';
    }

    init() {
        console.log('Cat init!');
    }

    say () {
        console.log('meo');
    }

}

let cat = new Cat()
cat.say();
cat.sayName();