你能从JavaScript的基类中获得派生类吗?

Can you get the dervied class from the base class in JavaScript?

本文关键字:派生 JavaScript 基类      更新时间:2023-09-26

下面演示了我试图实现的目标。我有一个名为X的基类,它不做任何事情以…

function X() {
}

声明了一个继承自x的名为Y的派生类。它还在名为name的派生类上设置了一个属性。这并不意味着对每个实例都适用,因此放在类本身上。

function Y() {
  X.call(this);
}
Y.prototype = new X();
Y.name = 'Y';

我们添加了另一个来自x的名为Z的派生类,这次它为name属性设置了一个不同的值。

function Z() {
  X.call(this);
}
Z.prototype = new X();
Z.name = 'Z';

现在,从实际的基类中,我希望能够测试和使用任何派生类的name属性。我找不到实现这一目标的方法。所以理想情况下它应该是这样的…

function X() {
    console.log(???.name);
}

当然,我不知道在???以在调用基类构造函数时获取实际的派生类实例。也许这是不可能的?

更好的是能够遍历类链,如果有从Y或Z派生的类,我也可以获得name的所有中间值。如果这是不可能的,那么你能建议一个替代方法吗?

首先,适当地子类化,恢复constructor:

function X() {}
function Y() {
  X.call(this);
}
Y.prototype = Object.create(X.prototype);
Y.prototype.constructor = Y;
Y.name = 'Y';
function Z() {
  X.call(this);
}
Z.prototype = Object.create(X.prototype);
Z.prototype.constructor = Z;
Z.name = 'Z';

那么你可以使用this.constructor.name

function X() {
  this.theName = this.constructor.name;
}
function Y() {
  X.call(this);
}
Y.prototype = Object.create(X.prototype);
Y.prototype.constructor = Y;
Y.name = 'Y';
function Z() {
  X.call(this);
}
Z.prototype = Object.create(X.prototype);
Z.prototype.constructor = Z;
Z.name = 'Z';
document.write(new Y().theName + '<br />' + new Z().theName);

注意使用name属性可能会有问题。前段时间,一些浏览器在函数中实现了一个非标准的不可写的name属性。ES6对它进行了标准化,现在它是可写的,但在旧的浏览器上可能会出现问题。

所以最好使用另一个名称,或者将其存储在prototype .

function X() {
  this.theName = this.name;
}
function Y() {
  X.call(this);
}
Y.prototype = Object.create(X.prototype);
Y.prototype.constructor = Y;
Y.prototype.name = 'Y';
function Z() {
  X.call(this);
}
Z.prototype = Object.create(X.prototype);
Z.prototype.constructor = Z;
Z.prototype.name = 'Z';
document.write(new Y().theName + '<br />' + new Z().theName);

你真的不应该在javascript中使用类设计模式:它的工作方式与java不同。

试试这个

    var original = {
    setName: function(name) {this.name = name};
    }
    var newObject = Object.create(original);

不创建副本,而是继承变量original作为原型,并且可以访问它的属性,以便在新对象上使用。

    newObject.setName(tony);
console.log(newObject.name);