3

How can I call the following?

var ccall="search.clearMultiSelect";

I have tried the following:

  1. window[ccall]();
  2. ccall();

Both didn't work (and I get why). I was able to achieve it by eval but is there any other way without using eval?

I cannot split the string or manipulate the string, except for adding something at the beginning or end.

Basically the server, in it's response, contains the name of the function to execute on success of an operation, which in this case is as above.

Metalskin
  • 3,998
  • 5
  • 37
  • 61
aWebDeveloper
  • 36,687
  • 39
  • 170
  • 242
  • Have you read this questions? http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string – Oyeme Jan 21 '14 at 09:55
  • 2
    Under what circumstances would you be prohibited from splitting the string, if you are planning to write code to call from it? – CodingIntrigue Jan 21 '14 at 09:56
  • 1
    Still doesn't answer why you couldn't just split on the string, but just use `eval`. What you're doing here will suffer from injection attacks no matter what method you use. – CodingIntrigue Jan 21 '14 at 10:00
  • I agree with @RGraham, this is a bad practice: causes a strong coupling. – Pablo Lozano Jan 21 '14 at 11:05

4 Answers4

3

window[ccall]() wouldn't work because window doesn't contain a function by the name "search.clearMultiSelect". If you can use split, try something like:

window[ccall.split('.')[0]][ccall.split('.')[1]]();

For a function of depth greater than 2, you can loop through the split('.') array:

var f = window;
var ccallArray = ccall.split('.');
for (var i = 0; i < ccallArray.length; i++){
    f = f[ccallArray[i]];
}
f();

DEMO

tewathia
  • 6,890
  • 3
  • 22
  • 27
2

You must have a finite number of functions to call.

To protect against eval issues, you could manually do:

if (ccall == "search.func1") func1();
else if (ccall == "search.func2") func2();
else if ....

Not a very exciting answer, but it should work and avoid an eval.

This also decouples your client and sever.

The server can send back search.func1 while the client decides to respond by calling newfunc1() or vice versa.

MikeHelland
  • 1,151
  • 1
  • 7
  • 17
  • I think it's the best solution since any other, especially using eval or even splitting the string will be exposed to different kinds of attacks. @MazeHatter you could use `switch` instead of `if`s. – Michał Miszczyszyn Jan 21 '14 at 12:07
1

You could split the string along the '.' and then use repeated lookups with [].

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • 3
    I can see no reason why your client program cannot do whatever it wants to to a string it receives from the server... This seems a good idea to try to me. – virtualnobi Jan 21 '14 at 11:00
-3

You can use eval().

Here is a little example :

var myFunction = "alert('test');";
eval(myFunction);

Here is a link to test the example above:

http://jsfiddle.net/labzus/WzpK8/

labzus
  • 137
  • 1
  • 5