以下说明了我想要实现的目标。我有一个名为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的类,那么走向类链的能力就更好了。我也可以得到名称的所有中间值。如果这是不可能的,那么你能建议一种替代方法吗?
答案 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);