Typescript / Javascript:按字符串名称调用函数

时间:2020-06-18 08:59:49

标签: javascript typescript

我有一个*.ts文件,其中包含许多导出功能,例如:

export function newItemFoo() {
    return {foo: 0, bar: '', baz: true};
}

export function newItemBar() {
    return {foo: 0, bar: ''};
}

export function newItemXXX() {
    return {xxx: 0};
}

我想制作一个“魔术方法”(在同一*.ts中),该魔术方法可以按名称调用这些方法之一,例如:

export function magicMethod(name: string) {
    const newEmptyFunc = new Function(`return new${name}()`);
    return newEmptyFunc();
}
magicMethod('ItemFoo');

但是会引发错误

错误:未定义newItemFoo

它与eval一起使用:

export function magicMethod(name: string) {
    return eval(`newEmpty${name}()`);
}
magicMethod('ItemFoo');

如何使用new Function()通过字符串名称调用函数?

1 个答案:

答案 0 :(得分:2)

同时使用eval()new Function()是达到目标的复杂方法。

尝试一种更简单的方法。创建一个对象,该对象提供要传递给magicMethod()的值和要调用的函数之间的映射。然后以这种方式实现magicMethod()

function newItemFoo() {
    return {foo: 0, bar: '', baz: true};
}

function newItemBar() {
    return {foo: 0, bar: ''};
}

function newItemXXX() {
    return {xxx: 0};
}

const magicWand: { [K: string]: Function } = {
   Foo: newItemFoo,
   Bar: newItemBar,
   xxx: newItemXXX,   // this allows you to use a different value for the argument
   yyy: newItemXXX,   // ... to use multiple names for the same function
                      // ... and to handle gracefully the calls of non-existing functions 
};

export function magicMethod(name: string) {
  if (magicWand[name]) {
    return magicWand[name]();
  }

  throw new Error(`Method '${name}' is not implemented.`);
}

用法:

magicMethod('Foo')
// { foo: 0, bar: '', baz: true }
magicMethod('Bar')
// { foo: 0, bar: '' }
magicMethod('xxx')
// { xxx: 0 }
magicMethod('yyy')
// { xxx: 0 }
magicMethod('zzz')
// Error: Method 'zzz' is not implemented.

但是,如果提供了一种机制来调用模块定义的功能,则可能不想使用标准的export机制将其公开,而只是通过magicMethod()公开。这是唯一需要export编辑的函数。