如何通过原型实现经典类继承

2024-01-24

我想在 JS 中实现以下行为。请注意,语法是符号性的。

这是我的家长班

class = TList {
   FList: array;

   function AddElement(Ele) {
        Flist.Add(Ele)
   };

   function RemoveEle(Ele) {
        FList.Remove(Ele)
   };   
}

现在我要继承这个类。我的子类应该自动具有父类的所有属性,并且应该能够扩展它们而无需重写代码。

class = TAlertList(inherit from TList) {

   function AddElement(Ele) {
      Alert('element will be added');
      call.parent.AddElement(Ele)
   };

   function RemoveElement(Ele) {
     call.parent.RemoveElement(Ele);
     Alert('element removed');
   }

}

请注意我如何在我希望的地方继承父方法。

现在我应该能够从我的子类创建一个对象并执行以下操作。

MyAlertList = new TAlertList;
MyAlertList.Add('hello');
console.log(MyAlertList.FList);

我应该能够从 TAlertList 继承更多子类,并能够更改现有的行为。我需要在纯 ES5 中执行此操作,而不使用任何库。标准的 OOP 实践是预期的。


请注意,TList构造函数应该应用于TAlertList实例;

ES5,首先设置基础构造函数

function TList() {
    this.Flist = [];
    // ...
}

TList.prototype = {
    constructor: TList,
    AddElement: function AddElement(Ele) {
        this.Flist.push(Ele);
    },
    RemoveEle: function RemoveEle(Ele) {
        var i = this.Flist.lastIndexOf(Ele);
        if (i !== -1)
            this.Flist.splice(i, 1);
    }
};

接下来设置扩展它的构造函数,看看这意味着如何在扩展构造函数创建的实例上调用基本构造函数,并创建一个继承基本构造函数原型的原型对象

function TAlertList() {
    // construct from base
    TList.call(this);
    // further construct
    // ...
}
TAlertList.prototype = Object.create(TList.prototype);
TAlertList.prototype.constructor = TAlertList;

// depending on how you want to reference stuff
TAlertList.prototype.AddElement = function AddElement(Ele) {
    alert('element will be added');
    TList.prototype.AddElement.call(this, Ele);
};
TAlertList.prototype.RemoveElement = function RemoveElement(Ele) {
    TList.prototype.RemoveEle.call(this, Ele);
    alert('element removed');
};

ES6 语法使用super keyword

class TList {
    constructor() {
        this.FList = [];
    }
    AddElement(Ele) {
        this.Flist.push(Ele);
    }
    RemoveEle(Ele) {
        var i = this.Flist.lastIndexOf(Ele);
        if (i !== -1)
            this.Flist.splice(i, 1);
    }
}

class TAlertList extends TList {
    constructor() {
        super();
    }
    AddElement(Ele) {
        alert('element will be added');
        super.AddElement(Ele);
    }
    RemoveElement(Ele) {
        super.RemoveEle(Ele);
        alert('element removed');
    }
}

回到 ES5,概括为一个工厂,这样你就可以看到一种如何做的算法

function extend(baseConstructor, extendedConstructor, prototypeLayer) {
    function Constructor() {
        var i = 0, j = 0, args = Array.prototype.slice.call(arguments);

        i = j, j += baseConstructor.length;
        baseConstructor.apply(this, args.slice(i, j));

        i = j, j = args.length;
        extendedConstructor.apply(this, args.slice(i, j));
    }
    Object.defineProperty(Constructor, 'length', { // fix .length
        value: baseConstructor.length + extendedConstructor.length,
        configurable: true
    });
    Constructor.prototype = Object.create(baseConstructor.prototype);
    Constructor.prototype.constructor = Constructor;
    Object.assign(Constructor.prototype, prototypeLayer);
    return Constructor;
}

So then

function Foo(x) {this.foo = x;}
Foo.prototype.fizz = 1;
var Bar = extend(Foo, function (x) {this.bar = x;}, {buzz: 1});
// ...
var b = new Bar('foo', 'bar');
b.foo; // "foo"
b.bar; // "bar"
b instanceof Foo; // true
b instanceof Bar; // true
b.fizz; // 1
b.buzz; // 1

请注意,这是您在编写每个扩展构造函数时应遵循的算法示例,而不是生产代码

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何通过原型实现经典类继承 的相关文章

随机推荐