在javascript中如何检索实现的子类名称

时间:2009-05-16 23:16:25

标签: javascript inheritance

说我有一个像这样的“抽象类”:

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')* /

感谢

3 个答案:

答案 0 :(得分:3)

你知道,AbstractClassImplementingClass都只是功能。 Javascript中的函数(以及ECMAScript中的函数)通常没有任何类似字符串的“name”值。在这种情况下,AbstractClassImplementingClass是功能 标识符 ;这些标识符只是每个函数声明的生成的一部分(但并不总是函数表达式,这就是函数表达式可以匿名的原因)。

在某些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”字符串),遗憾的是,只能使用evalFunction构造函数(两者都是 - 不太理想的解决方案)来避免重复。

如果您需要实例对象来了解其构造函数的“名称”,那么使用某种抽象实现类似的“搭载”应该是微不足道的。

答案 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" */