I have 2 Class defined somewhere else, all constructors need 3 parameters (a, b, c), but a, b(object), c(object) is in an Array
var paramArr = [a, b, c];
I would like to call these 2 Class via a parameter according to a dictionary object, like:
var dict = {'a': 'A', 'b': 'B'};
then,
callClass(x){
var className = dict[x];//string
new className();
}
So, first I tried to do is something like eval so that I could call the Class with it string name.
callClass(x){
var className = dict[x];//string
var classFn = new Function(this, 'new ' + className + '()');
classFn();
}
still works fine. at last I should add the args by Fn.prototype.apply(), then I had to say all messed up:
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();
}
the classFn in the console will be:
function(this){
return new (Function.prototype.bind.apply(Classname, , a ,[object Object],[object Object]))
}
it is something I expected but not all:
first, the 'null' value in the array is converted to disappeared, which leads to 'unexpected token ,'
second, all the other objects are converted to '[object Object]', which leads to 'unexpected identifier'
So, how could I apply a array param with null value? or this is a wrong way to do this?
If I understand correct, you are trying to create object where class/constructor name is dynamically decided. For this, you can try using eval
.
Idea
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)
})
Idea of this approach is to have a list of possible classes with a map and use it to get reference dynamically. This is better/preferred than eval
approach but it comes with an overhead of maintaining the map.
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)
})