你能从JavaScript的基类中得到这个类吗?

时间:2015-09-25 00:18:02

标签: javascript ecmascript-5

以下说明了我想要实现的目标。我有一个名为X的基类,它不会开始......

function X() {
}

我声明了一个名为Y的派生类,它继承自X.它还在名为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的类,那么走向类链的能力就更好了。我也可以得到名称的所有中间值。如果这是不可能的,那么你能建议一种替代方法吗?

2 个答案:

答案 0 :(得分:2)

首先,正确地进行子类化,恢复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);

答案 1 :(得分:0)

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

试试这个。

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

    var newObject = Object.create(original);

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

    newObject.setName(tony);

console.log(newObject.name);