Typescript/Javascript: Kall funksjon etter strengnavn
Jeg har en *.ts-fil med mange eksporterte funksjoner som:
export function newItemFoo() {
return {foo: 0, bar: '', baz: true};
}
export function newItemBar() {
return {foo: 0, bar: ''};
}
export function newItemXXX() {
return {xxx: 0};
}
Jeg vil lage en "magisk metode" (i samme *.ts) som kan kalle en av disse metodene etter navn, f.eks:
export function magicMethod(name: string) {
const newEmptyFunc = new Function(`return new${name}()`);
return newEmptyFunc();
}
magicMethod('ItemFoo');
men det gir en feil
Feil: newItemFoo er ikke definert
Det fungerer med eval:
export function magicMethod(name: string) {
return eval(`newEmpty${name}()`);
}
magicMethod('ItemFoo');
Hvordan kaller jeg en funksjon ved strengnavn med new Function()?
Svar #1
Både bruk av eval() og new Function() er innviklede måter å oppnå målet på.
Prøv en enklere tilnærming. Opprett et objekt som gir en avbildning mellom verdiene du vil sende til magicMethod() og funksjonene som skal kalles. Implementer deretter magicMethod() på denne måten:
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.`);
}
Bruk:
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.
Men hvis du gir en slik mekanisme for å kalle funksjonene definert av modulen, vil du sannsynligvis ikke gjøre dem offentlige ved hjelp av standard export-mekanismen, men bare gjennom magicMethod(). Det er den eneste funksjonen som trenger å bli export-ert.
