We all know that eval is evil, right? Every once in a while, I run across a situation where it is very tempting to just use “eval”, but in general I avoid it.
Granted, there are acceptable reasons to use “eval”, but I have a hard time justifying a new instance of the JavaScript compiler just for convenience. (…Not to mention debugging and scope issues)
I was tempted today by the following scenario:
The application I was working on was providing a series of string values that represented different JavaScript objects/functions (nicely namespaced for once, I mightadd). Depending on a user’s actions, the values vary. In order to complete the functionality, I needed these strings to be actual objects.
Here is a simplified example of one of the strings:
‘Company.info.image.upload’ …where the last object (upload) is a function
I could have just: eval(‘Company.info.image.upload’ + ‘()’);
However, it would be a much cleaner solution if I were able to control the scope of the function/object being called. So, without using eval, how do you execute a method for which you only have the string representation?
var someString = 'Company.info.image.upload',
arObj = someString.split('.'),
obj = window;
for (var i = 0, len = arObj.length; i < len; i++) { obj = obj[arObj[i]]; }
if (obj !== window) { obj.apply(this); }
//P.S. I love associative arrays in javascript
That’s it! Build the object in the loop and execute the method using apply().
A couple of quick notes:
- It is important to keep in mind that eventthough the “upload” method is namespaced, it is still ultimately a child object of the window object. (i.e. Company.info.image.upload is actually window.Company.info.image.upload)
- Similarly, it is worth noting that I used the apply method so that I could pass in the desired scope
Some informative links: