【问题标题】:Determine if class of given name exists确定给定名称的类是否存在
【发布时间】:2018-03-16 09:25:17
【问题描述】:

这可能是一个愚蠢的问题,但我四处寻找,一无所获。

我有一个代码:

class A {}

let className = 'A';

我需要检查className 是否对应于现有的类。

这都不在全局范围内,并且在 node.js 中运行,所以我不能使用window

我知道以下方法会起作用:

eval(`typeof ${className} === 'function'`);

但是我有点不愿意使用eval(而且 linter 也抱怨它)

此外,我还需要将类实例化为一个变量,我可以再次使用 eval 像这样:

 let ctor = eval(className);
 let object = new ctor();

但这又使用了 eval。

有没有其他方法可以实现这些?

【问题讨论】:

  • 类不在全局范围内吗?这个类是另一个类或作用域的私有成员吗?
  • @gurvinder372 这不在全局范围内,它在一个模块中
  • 如果它没有从那个模块中暴露出来,那么你打算如何首先到达它?
  • @gurvinder372 我可能误解了你的初衷。是的,它在一个模块中,但检查字符串是否是该模块中可见的类的代码也是如此
  • 如果不是eval,那么你可以使用Function构造函数,它不会立即计算函数体。

标签: javascript ecmascript-6


【解决方案1】:

这可能表明错误的设计决策和可能的 XY 问题。对eval 的需求通常表明了这一点。跟踪正在使用的类是开发人员的责任。

如果导出函数,可以检查module.exports。如果它们没有被导出,它们可能应该被导出。

如果要跟踪的类不止一个模块,则可以使用容器,并且应该显式注册函数:

const globalClassContainer = new Map;
function registerClass(cls) {
  if (globalClassContainer.has(cls.name))
    globalClassContainer.set(cls.name, new Set);

  globalClassContainer.get(cls.name).add(cls);
}

class Foo {};
registerClass(Foo);

函数不应该通过它们的名称明确地标识,名称应该仅用于调试目的。可以有多个函数具有相同的name(即使在当前范围内),也可以有与name 不匹配的函数。函数name 在 Node.js 中往往更安全,但不能保证安全:

class Foo {}
const Bar = Foo; // Bar.name === 'Foo';

const bazFactory = () => class {};
const Baz = bazFactory(); // Baz.name === '';

【讨论】:

    【解决方案2】:

    使用Function构造函数

    function ac(){} //new class
    var f = new Function( "return typeof ac == 'function'" ) //define function to verify
    f(); //returns true if class exists in the current scope
    

    让它更通用

    function ac(){} //new class
    var f = function( className ){
      return new Function( "return typeof " + className + " == 'function'" )(); //define function to verify and invoke the same
    } 
    f( "ac" ); //returns true if class exists in the current scope
    

    【讨论】:

    • 嗯,这在技术上不是eval,但它也是eval 我从中得到的是,使用某种eval 似乎是不可避免的。
    猜你喜欢
    • 2014-03-08
    • 2012-05-09
    • 1970-01-01
    • 2010-12-27
    • 2020-12-28
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 2015-07-09
    相关资源
    最近更新 更多