I'd like to use new Function(...)
to generate a function from very reduced code. I'l like to do this to
I avoid eval()
whenever possible. But I'm not sure if it's secure enough to use new Function(...)
which is also known as being liable to security holes.
I want to manage the states of menu buttons. So, while defining the buttons, I'd like to write something like
{
..., // More button definition
state: "isInEditmode && (isWidgetSelected || isCursorInWidget),
...
}
While handling the statechange during several events I'll check (summarize) the states of the current overall state object against those in the states
attribute.
So I'll generate a Function during rendertime and attaching it as a DOM object attribute, not DOM attribute this way:
...
$el.stateFn = new Function("stateObj", "with (stateObj) {return " + item.state + ";}");
...
Testing state:
visible = $el.stateFn.call(currentStates, currentStates);
The with
statement helps me providing the current state
object's attributes as variables so that the above expression does not need something like obj.isInEditmode
.
In my opinion this does not introduce security holes as the function attached to the DOM object is generated during render time and read from source. Or am I wrong? Should I avoid this?
Performance hints are appreciated (comment) (I think as long as I evaluating a new Function
once during render time, this is acceptable).
Security-wise both are just as bad if user input is allowed to break out in the code. However, maintenance wise you don't have to worry about hidden bugs when local eval messes with your scope and causes dynamic scoping.
Performance-wise the function generated by new Function
is exactly the same as any other function. The generation is slower but inlike eval
it doesn't cause the containing scope to be unoptimizable.
In fact, new Function
can be used to improve performance in situations like:
//Will behave like function a( obj ) { return obj.something }
function makePropReader( propName ) {
return new Function( "obj", "return obj." + propName );
}
The constructed function will perform better than the function returned here:
function makePropReader( propName ) {
return function( obj ) {
return obj[propName];
}
}
Due to having to dynamically read propName
from closure context and do a dynamic read on the object everytime it is called.