说我有一个像这样的“抽象类”:
function AbstractClass() {
this.getImplementingName = function() {
return /* how do I get this? */;
}
}
和像
这样的实现function ImplmentingClass() {
}
ImplmentingClass.prototype = new AbstractClass();
var impl = new ImplmentingClass()
var name = impl.getImplementingName();
/ *我如何得到...(name =='ImplementingClass')* /
感谢
答案 0 :(得分:3)
你知道,AbstractClass
和ImplementingClass
都只是功能。 Javascript中的函数(以及ECMAScript中的函数)通常没有任何类似字符串的“name”值。在这种情况下,AbstractClass
和ImplementingClass
是功能 标识符 ;这些标识符只是每个函数声明的生成的一部分(但并不总是函数表达式,这就是函数表达式可以匿名的原因)。
在某些ES3实现中,在创建函数期间,此标识符的值将自动分配给函数对象的 name 属性。当然,这是一种非标准的扩展,目前由一些基于Gecko和WebKit的浏览器实现。它也正在由ES委员会讨论,并可能会进入ECMAScript的未来版本。
(function foo(){}).name; // "foo" in Safari 4.x and FF 3.x
还有 toString方法,可通过Function.prototype.toString
在所有Function对象上使用:
String(function foo(){}); // "function foo() {}"
不幸的是,ECMAScript指定此方法返回依赖于实现的函数表示,因此依赖于解析此值是相当脆弱的。这种解析被称为函数反编译,并且通常建议不要使用它,因为它是非标准和古怪的(我写过some of these quirks几次)。请注意,下一版本的ECMAScript(ES5,当前草稿)也不会更改这些规则。
您最好的选择是手动分配财产或使用某种类似工厂的帮手。 E.g:
function initFn(name, fn) {
fn.name = name;
return fn;
}
// and then
var AbstractClass = initFn('AbstractClass', function(){
// ...
});
// or directly
function foo(){}
foo.name = 'foo';
请注意这里的重复(“AbstractClass”字符串),遗憾的是,只能使用eval
或Function
构造函数(两者都是 - 不太理想的解决方案)来避免重复。
如果您需要实例对象来了解其构造函数的“名称”,那么使用某种抽象实现类似的“搭载”应该是微不足道的。
答案 1 :(得分:1)
检查.constructor属性(和/或instanceof运算符)
答案 2 :(得分:1)
我认为没有直接的方法来做你想要完成的事情,但这就是我接近它的方式。我会覆盖implementClass中的toString()。
function AbstractClass() {
this.getImplementingName = function() {
return this.toString();
}
}
function ImplmentingClass() {
this.toString = function(){return "ImplementingClass";}
}
ImplmentingClass.prototype = new AbstractClass();
var impl = new ImplmentingClass()
var name = impl.getImplementingName(); /* name equals "ImplementingClass" */