我处于一种奇怪的情况下,我需要使用存储在变量中的字符串实例化一个新的类,但是即使我确定类名正确,我也会收到一个错误,即给定的类名不是构造函数
这是一个无效的伪代码:
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()
或者可以先对其进行清理,那么它可能是安全的。
我个人更希望使用查找表。如果您有已知数量的要按字符串映射的类,则可以创建自己的查找表并使用它。这样做的好处是,如果字符串中包含奇怪的内容,则不会有意外的结果:
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
由于以下几个原因,这应该比使用全局或对象作为查找机制更好:
如果我还记得的话,class
ES6中的定义不会像其他顶级变量声明那样自动地放到全局对象上(JavaScript试图避免在先前的设计错误之上添加更多的垃圾)。
因此,如果要手动分配给查找对象,则不妨使用其他对象而不污染全局对象。这就是该dict
对象用于此处的目的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句