根据输入数据使用括号表示法

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (6)

我正在优化我的库中的一些代码,但是,在尝试调用导入的类时,我有一个关于为什么括号表示法不起作用的问题。

参数type接受camelCased的字符串,例如:myString。参数data可以是任何东西。

import { foo } from './example';

export const find = (type: string, data: any) => {

// This next line effectively deletes the end of the string starting
// from the first capital letter.
    const f = type.replace(/[A-Z][a-z]+/, '');
    try {
        return [f][type](data);
    } catch (e) {
        return e;
    }
};

这就是我期望它看起来像我用点符号可视化它:

foo.fooBar(someRandomData)

这应该fooBar(data)在导入的类上调用静态方法foo,但是,我收到一条错误消息:

TypeError: [f][type] is not a function

如果我要将它恢复到我的if..else if风格,它的工作原理:

if (type.startsWith('foo')) return foo[type](data);

如何在不获取定义的错误消息的情况下执行上述操作?

提前谢谢你的帮助!

编辑:这是我从现有代码修改的一个例子,因此,我修复了一些拼写错误。 编辑#2:根据要求,导入的类foo看起来像这样:

export class foo{
static fooBar(data){
// Do stuff with data...
}
提问于
用户回答回答于

根据我的想法,您可以eval用来完成任务。您可以将代码修改为:

import { foo } from './example';

export const find = (type: string, data: any) => {

// This next line effectively deletes the end of the string starting
// from the first capital letter.
    const f = type.replace(/[A-Z][a-z]+/, '');
    try {
        return eval(f)[type](data);
    } catch (e) {
        return e;
    }
};

如果你打电话find('fooBar', someObject),那么上面的代码将结束通话foo.fooBar(someObject)

请注意,如果type字符串来自用户生成的输入,那么您将打开代码注入攻击,这意味着用户可以在您的服务器上执行任意代码,包括访问文件,数据库等或传播病毒或完全控制计算机。

这可能是最初使用多个if/else块编写代码的原因。

用户回答回答于

我建议你转而使用内置的nodeJS EventEmitter

你可以这样做:

import * as EventEmitter from 'events';

import { foo } from './example';
import { bar } from './example2';

export const discordEventEmitter = new EventEmitter();

discordEventEmitter.on('fooBar', foo.fooBar);
discordEventEmitter.on('fooToo', foo.fooToo);
discordEventEmitter.on('barBell', bar.barBell);

然后,当您想要发起一个事件时,您可以简单地:

discordEventEmitter.emit('fooBar', someData);

您还可以通过编写来简化事件处理程序注册:

const fooProps = Object.getOwnPropertyNames(foo) as (keyof typeof foo)[];
fooProps.forEach(funcName => {
  discordEventEmitter.on(funcName, foo[funcName]);
});

const barProps = Object.getOwnPropertyNames(bar) as (keyof typeof bar)[];
fooProps.forEach(funcName => {
  discordEventEmitter.on(funcName, bar[funcName]);
});

扫码关注云+社区

领取腾讯云代金券