我已经实现了一些模块,简化代码如下所示:
(function() {
var context = {...}; // an object which serves as the context for the expression being evaluated
with (context) {
var x = eval(expression);
...
}
}());
为了澄清,我可以完全控制表达式和动态创建的上下文对象。表达始终是安全的,并且是从可靠来源提供的出现在表达式中的所有成员(字段和函数)始终存在于上下文对象中,例如
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
...
}
现在,我想插入'use strict';
pragma作为模块的第一行(让我们假设出于某些原因我想要整个模块,我不想将严格性应用于缩小的集合函数范围和混合严格的代码与此模块中的草率一个)。
因此我需要更改我的代码以传递strict mode要求,因为正如ECMAScript 5.1规范中所述,严格模式下不允许with语句。
我通过以下修改来破坏兼容性:
(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);
...
}());
(故意没有给Function
构造函数添加额外的pragma,这种严格和草率的代码组合我可以接受)
与第一版相比,这种方法在性能或安全方面是否有任何缺点?您能否提供满足严格模式的更好的解决方案,保留相同的功能集?