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

ar0*_*968 1 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};
}
Run Code Online (Sandbox Code Playgroud)

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

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

但它引发了一个错误

错误:newItemFoo 未定义

它适用于 eval:

export function magicMethod(name: string) {
    return eval(`newEmpty${name}()`);
}
magicMethod('ItemFoo');
Run Code Online (Sandbox Code Playgroud)

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

axi*_*iac 5

使用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.`);
}
Run Code Online (Sandbox Code Playgroud)

用法:

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.
Run Code Online (Sandbox Code Playgroud)

但是,如果您提供这样一种机制来调用由模块定义的函数,您可能不希望使用标准export机制将它们公开,而只是通过magicMethod(). 它是唯一需要export-ed 的函数。