1

I have a method which sets a new instance to an array, created dynamically. How can I do that without the use of eval()?

var Form = (function(){
    function Form(params){
        this.shapesArray = [];
        this.shape;
        ...
    }

    Form.prototype.submit = function(){
        ... this.shape is the shape selected by the user ...
        this.setShape('new Shapes.' + this.shape + '(arg1, arg2, color)');
    }

    Form.prototype.setShape = function(obj){
        this.shapesArray.push(obj);
    }
return Form;
}());

So, how to call the setShape method by passing new instance to it without eval()?

This works so far:

Form.prototype.submit = function(){
    eval('this.setShape(new Shapes.'+ this.shape.capitalize() +'('+ str_params + '))');
}

But using eval() is not a good practice. How to achieve the same result wighout eval()?

Ezio_
  • 593
  • 3
  • 9
  • 23

1 Answers1

3

You may use the bracket notation to access the property :

this.setShape(new Shapes[this.shape](arg1, arg2, color));

Now, if you get your arguments from a dynamic array, it's a little more complex because you can't just use apply.

Here's a solution:

var constructor = new Shapes[this.shape];
var C = function(){
    return constructor.apply(this, arr_of_args);
}
C.prototype = constructor.prototype;
this.setShape(new C());

But this starts to get tricky and hard to read. A new design of your application not involving dynamic constructors having a variable number of arguments might be preferable.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • Thank you. Seems like it's working. How can I pass arguments, if the count of arguments is also dyamically created? How can I manage to use `apply`? Something like `this.setShape(new Shapes[this.shape].apply(null, arr_of_args));` – Ezio_ May 18 '15 at 13:16
  • @Ezio_ See edit. But I clearly wouldn't use something so complex just to create instances, there's probably a better design for your application (might be a map of factories for example). – Denys Séguret May 18 '15 at 13:27