I have implemented some module, which simplified code is shown below:
(function() {
var context = {...}; // an object which serves as the context for the expression being evaluated
with (context) {
var x = eval(expression);
...
}
}());
Just to clarify, I have full control over the expression and over dynamically created context object. Expression is always safe and provided from trusted source. All members (fields and functions) appearing in the expression always exist in the context object e.g.
var context = {
Concat: function(strA, strB) { return [strA, strB].join(''); },
Name: 'ABC',
Surname: 'DEF'
}
with (context) {
var x = eval("Concat(Name, Surname) == 'XYZ'"); // evaluates to false
...
}
Now, I'd like to insert the 'use strict';
pragma as the first line of the module (let's assume for some reasons I want this for entire module, I don't want to apply strictness to narrowed set of function scopes and mix strict code with sloppy one within this module).
Because of that I need to change my code to pass strict mode requirements, because, as noted in ECMAScript 5.1 specification, with statements are not allowed in strict mode.
I've hacked this by doing following modification to extort the compatibility:
(function() {
'use strict';
function ctxEval(exp, ctx) { // evaluates expression in the scope of context object
return (new Function('expression', 'context', 'with(context){return eval(expression)}'))(exp, ctx);
}
var context = {...};
var x = ctxEval(expression, context);
...
}());
(additional pragma intentionally not put to Function
constructor, this kind of strict and sloppy code mix I can accept)
Are there any drawbacks of this approach in terms of performance or safety when compared to first version? Can you provide any better solution which satisfies strict mode preserving the same set of functionality?