I set about asking this question wrongly, so I am starting again, beginning with the specifics of the issue I am wrestling with, rather than the general features of the issue.
I have an object in which the values are strings. They pretty much need to be strings because they are extracted from HTML5 custom data-*
attributes and I really don't want to start writing javascript inside HTML attributes, like it's 1999.
Here's an example of one of the custom data-*
attributes:
data-event="{«eventListener» : «transitionend», «eventAction» : «showText»}"
As you can see, it's basically a JSON string, slightly modified, so that it can take the form of an HTML attribute value.
I would like to be able to parse that custom data-*
attribute and translate it into the following javascript:
parentElement.addEventListener('transitionend', showText, false);
To do this, I need to:
«
and »
characters with the "
characterJSON.parse
the resulting value into an objectuseCapture
parameter if it doesn't exist (as in this example)addEventListener
statementIn fact - of course - I end up with this statement:
parentElement.addEventListener('transitionend', 'showText', false);
which doesn't work because I can't invoke 'showText'
- it's just a string, it doesn't point to a function.
The easiest way to fix this is to create this statement, instead:
parentElement.addEventListener('transitionend', eval('showText'), false);
which is equivalent to:
parentElement.addEventListener('transitionend', showText, false);
The only thing that's holding me back is my uncertainty over whether eval()
should really never be used or whether it should simply mostly be avoided - and, despite normal warnings, this unusual situation is an acceptable situation in which to deploy eval()
.
Question: Is it misguided or inadvisable in Javascript to take a string which happens to be the name of a function and to access and execute that function by using eval()
on the string?
If it is inadvisable, what is the alternative, when I know the name of a function and I wish to insert it into an event handler?
If I'm better off avoiding this:
parentElement.addEventListener('transitionend', eval('showText'), false);
what should I be using instead?
Or... is it entirely acceptable to use eval()
in some situations - and this is one of them?
In response to the update, you will be better off placing all event handlers in an object instead of the global namespace, that is:
before:
function showText(event) {
...
}
function anotherHandler(event) {
...
}
after:
const myActions = {
showText(event) {
...
},
anotherHandler(event) {
...
}
}
And then, after you've parsed the data
attribute and got something like this:
data = {"eventListener" : "transitionend", "eventAction" : "showText"}
bind the handler this way:
parentElement.addEventListener(
data.eventListener,
myActions[data.eventAction],
false)
This not only gets rid of eval
, but also helps organizing your code in a cleaner way.