如何在 JavaScript 中从字符串实例化一个类
Posted
技术标签:
【中文标题】如何在 JavaScript 中从字符串实例化一个类【英文标题】:How to instantiate a Class from a String in JavaScript 【发布时间】:2018-08-09 02:15:49 【问题描述】:我处于一个奇怪的情况,我需要使用存储在变量中的字符串来实例化一个新类,但即使我确定类名是正确的,我也会收到一个错误,即给定的类名不是构造函数
这是一个无效的伪代码:
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
【问题讨论】:
window.Foo = class ...
而不是 class Foo ...
您可能需要使用eval()
。
***.com/questions/31776949/…
【参考方案1】:
一种可能性是使用eval
。
class Foo
constructor()
console.log('Foo!');
;
const foo = 'Foo';
const bar = eval(`new $foo()`);
console.log(bar);
您必须评估在您的特定情况下使用eval()
的安全性。如果您知道要插入到运行 eval()
的代码中的字符串的来源,或者您可以先对其进行清理,那么它可能是安全的。
我个人更喜欢查找表。如果您有已知数量的要按字符串映射的类,那么您可以制作自己的查找表并使用它。这样做的好处是,如果字符串中有奇怪的东西,就不会产生意想不到的后果:
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
中找不到字符串时添加错误处理。
这应该比使用全局或Window
对象作为您的查找机制更好,原因如下:
如果我记得,ES6 中的class
定义不会像其他***变量声明那样自动放在全局对象上(javascript 试图避免在先前的设计错误之上添加更多垃圾)。
因此,如果您要手动分配给查找对象,您不妨使用不同的对象而不污染全局对象。这就是dict
对象在这里的用途。
【讨论】:
第二个选项的问题在于Open for Extension Close for Modification 原则。但我想至少这样改变的地方减少了 2.【参考方案2】:类似于@jfriend00 ...
let className = "Foo";
let dynamicConstructor = ;
dynamicConstructor[className] = class
constructor()
console.log('Foo!');
;
let fooInstance = new dynamicConstructor[className]();
console.debug(fooInstance);
也可以使用一种工厂类构造函数
const classFactory = (_className)=>
let dynamicConstructor = ;
dynamicConstructor[_className] = class
constructor(_code)
this.code = _code;
console.log(`$_className initialised with code: $_code!`);
;
return dynamicConstructor[_className];
const MyClass = classFactory("Foo");
let fooInstance2 = new MyClass(123);
console.debug(fooInstance2);
【讨论】:
以上是关于如何在 JavaScript 中从字符串实例化一个类的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 5.0 中从 AppDelegate 实例化窗口失败 [重复]
如何在 JavaScript 中从末尾切分字符串? [复制]