如何通过字符串类型名称新建 Class 并在其中应用具有空值的数组参数?
How to new a Class by it's string type name and apply a array parameter inside which has null value?
我在别处定义了2个Class,所有的构造函数都需要3个
参数(a, b, c),但是a, b(object), c(object)在一个Array
var paramArr = [a, b, c];
我想根据字典对象通过参数调用这 2 个 Class,例如:
var dict = {'a': 'A', 'b': 'B'};
然后,
callClass(x){
var className = dict[x];//string
new className();
}
所以,首先我尝试做类似 eval 的事情,这样我就可以用它的字符串名称调用 Class。
callClass(x){
var className = dict[x];//string
var classFn = new Function(this, 'new ' + className + '()');
classFn();
}
仍然可以正常工作。最后我应该通过 Fn.prototype.apply() 添加 args,然后我不得不说一切都搞砸了:
callClass(x){
var className = dict[x];//string
paramArr.unshift(null);
var functionBodyStr = 'return new (Function.prototype.bind.apply(' + className + ', '+ paramArr +'))';
var classFn = new Function(this, functionBodyStr);
classFn();
}
控制台中的 classFn 将是:
function(this){
return new (Function.prototype.bind.apply(Classname, , a ,[object Object],[object Object]))
}
这是我所期望的,但不是全部:
首先将数组中的'null'值转换为消失,从而导致'unexpected token ,'
其次,所有其他对象都转换为'[object Object]',这导致'unexpected identifier'
那么,我怎样才能应用具有空值的数组参数呢?或者这是错误的方法?
如果我理解正确,您正在尝试创建 class/constructor 名称动态确定的对象。为此,您可以尝试使用 eval
.
使用评估
想法
- 根据您的要求创建 class/constructor 名称。
- 使用 eval 查找此函数并获取其作用域。
- 如果找到,可以直接使用
new fn(...)
- 如果没有找到,它会抛出错误,所以你必须处理这种情况。
function MyClass1(a, b, c) {
this.a = a;
this.b = b;
this.c = c
}
function MyClass2(a, b, c) {
this.a = a;
this.b = b;
this.c = c
}
var classPrefix = 'MyClass';
var result = [];
for (var i = 0; i < 5; i++) {
var functionName = classPrefix + (i % 3 + 1);
var fn;
try {
fn = eval(functionName);
result.push(new fn(i, i+1, i+2));
} catch (ex) {
console.log(functionName + ' was not found. Please check again.')
}
}
result.forEach(function(obj) {
console.log(obj.constructor.name, obj.a)
})
参考文献:
- Eval is evil
- Why exactly is eval evil?
使用 HashMap
这种方法的想法是使用地图列出可能的 类 并使用它来动态获取参考。这是 better/preferred 而非 eval
的方法,但它会带来维护地图的开销。
function MyClass1(a, b, c) {
this.a = a;
this.b = b;
this.c = c
}
function MyClass2(a, b, c) {
this.a = a;
this.b = b;
this.c = c
}
var functionMapper = {
'MyClass1': MyClass1,
'MyClass2': MyClass2,
}
var classPrefix = 'MyClass';
var result = [];
for (var i = 0; i < 5; i++) {
var functionName = classPrefix + (i % 3 + 1);
var fn = functionMapper[functionName];
fn && result.push(new fn(i, i+1, i+2));
}
result.forEach(function(obj) {
console.log(obj.constructor.name, obj.a)
})
我在别处定义了2个Class,所有的构造函数都需要3个 参数(a, b, c),但是a, b(object), c(object)在一个Array
var paramArr = [a, b, c];
我想根据字典对象通过参数调用这 2 个 Class,例如:
var dict = {'a': 'A', 'b': 'B'};
然后,
callClass(x){ var className = dict[x];//string new className(); }
所以,首先我尝试做类似 eval 的事情,这样我就可以用它的字符串名称调用 Class。
callClass(x){ var className = dict[x];//string var classFn = new Function(this, 'new ' + className + '()'); classFn(); }
仍然可以正常工作。最后我应该通过 Fn.prototype.apply() 添加 args,然后我不得不说一切都搞砸了:
callClass(x){ var className = dict[x];//string paramArr.unshift(null); var functionBodyStr = 'return new (Function.prototype.bind.apply(' + className + ', '+ paramArr +'))'; var classFn = new Function(this, functionBodyStr); classFn(); }
控制台中的 classFn 将是:
function(this){
return new (Function.prototype.bind.apply(Classname, , a ,[object Object],[object Object]))
}
这是我所期望的,但不是全部:
首先将数组中的'null'值转换为消失,从而导致'unexpected token ,'
其次,所有其他对象都转换为'[object Object]',这导致'unexpected identifier'
那么,我怎样才能应用具有空值的数组参数呢?或者这是错误的方法?
如果我理解正确,您正在尝试创建 class/constructor 名称动态确定的对象。为此,您可以尝试使用 eval
.
使用评估
想法
- 根据您的要求创建 class/constructor 名称。
- 使用 eval 查找此函数并获取其作用域。
- 如果找到,可以直接使用
new fn(...)
- 如果没有找到,它会抛出错误,所以你必须处理这种情况。
function MyClass1(a, b, c) {
this.a = a;
this.b = b;
this.c = c
}
function MyClass2(a, b, c) {
this.a = a;
this.b = b;
this.c = c
}
var classPrefix = 'MyClass';
var result = [];
for (var i = 0; i < 5; i++) {
var functionName = classPrefix + (i % 3 + 1);
var fn;
try {
fn = eval(functionName);
result.push(new fn(i, i+1, i+2));
} catch (ex) {
console.log(functionName + ' was not found. Please check again.')
}
}
result.forEach(function(obj) {
console.log(obj.constructor.name, obj.a)
})
参考文献:
- Eval is evil
- Why exactly is eval evil?
使用 HashMap
这种方法的想法是使用地图列出可能的 类 并使用它来动态获取参考。这是 better/preferred 而非 eval
的方法,但它会带来维护地图的开销。
function MyClass1(a, b, c) {
this.a = a;
this.b = b;
this.c = c
}
function MyClass2(a, b, c) {
this.a = a;
this.b = b;
this.c = c
}
var functionMapper = {
'MyClass1': MyClass1,
'MyClass2': MyClass2,
}
var classPrefix = 'MyClass';
var result = [];
for (var i = 0; i < 5; i++) {
var functionName = classPrefix + (i % 3 + 1);
var fn = functionMapper[functionName];
fn && result.push(new fn(i, i+1, i+2));
}
result.forEach(function(obj) {
console.log(obj.constructor.name, obj.a)
})