如何从JavaScript中的字符串实例化类 [英] How to instantiate a Class from a String in JavaScript

查看:97
本文介绍了如何从JavaScript中的字符串实例化类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我处于一种奇怪的情况下,我需要使用存储在变量中的字符串实例化一个新的Class,但是即使我确定该类名是正确的,我也会收到一个错误,即给定的类名不是构造函数

I'm in a weird situation that i need to instantiate a new Class with a string stored in a variable but even i'm sure the class name is correct i get an error that given class name is not a constructor

这是一个无效的伪代码:

Here is a dummy code that doesn't work:

class Foo {
    constructor(){
        console.log('Foo!');
    }
};
const foo = 'Foo';
const bar = new window[foo]();
console.log(bar);

此错误提示:

Uncaught TypeError: window[foo] is not a constructor


推荐答案

一种可能性是使用 eval

class Foo {
    constructor(){
        console.log('Foo!');
    }
};
const foo = 'Foo';
const bar = eval(`new ${foo}()`);
console.log(bar);

您必须评估使用 eval()在您的特定情况下。如果您知道要插入到运行 eval()的代码中的字符串的起源,或者可以先对其进行清理,那么它可能是安全的。

You will have to evaluate the safety of using eval() in your particular circumstances. If you know the origin of the string you are inserting into the code that you run eval() on or you can sanitize it first, then it may be safe.

我个人更喜欢查找表。如果您有已知数量的要按字符串映射的类,则可以创建自己的查找表并使用它。这样做的好处是,如果字符串中包含奇怪的内容,就不会有意外的结果:

I personally would prefer a lookup table. If you have a known number of classes that you want to map by string, then you can make your own lookup table and use that. This has the advantage of there can be no unintended consequences if the string has weird stuff in it:

class Foo {
    constructor(){
        console.log('Foo!');
    }
};

class Goo {
    constructor(){
        console.log('Goo!');
    }
};

// construct dict object that contains our mapping between strings and classes    
const dict = new Map([['Foo', Foo], ['Goo', Goo]]);

// make a class from a string
const foo = 'Foo';
let bar = new (dict.get(foo))()

console.log(bar);

如果您真的要走这条路线,则可能希望将其封装在一个函数中,然后如果在 dict 中找不到该字符串,则添加错误处理。

If you were really going to go this route, you may want to encapsulate it in a function and then add error handling if the string is not found in the dict.

这应该比使用global或 Window 对象作为您的查找机制有几个原因:

This should be better than using the global or Window object as your lookup mechanism for a couple reasons:


  1. 如果我记得,ES6中的 class 定义不会像在其他顶级变量声明中那样自动地放到全局对象上(Javascript试图避免在现有设计之上添加更多垃圾错误)。

  1. If I recall, class definitions in ES6 are not automatically put on the global object like they would with other top level variable declarations (Javascript trying to avoid adding more junk on top of prior design mistakes).

因此,如果您要手动分配给查找对象,则最好使用其他对象而不污染全局对象。这就是 dict 对象在这里使用的。

So, if you're going to manually assign to a lookup object, you might as well use a different object and not pollute the global object. That's what the dict object is used for here.

这篇关于如何从JavaScript中的字符串实例化类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆