如何解决JavaScript范围内的eval,未定义值
| 作为模板引擎的一部分,我需要能够评估JavaScript中的表达式,例如: 全局命名空间的某些对象服务角色中的“ 0”。因此,对象的属性应视为全局变量。 到目前为止,我想到了这个功能:function scopedEval(str,scope) {
var f = new Function(\"scope\",\"with(scope) { return (\" + str + \"); }\");
return f(scope);
}
一切都很好,我可以将其运行为:
var scope = { first:1,second:2 };
var expr1 = \"first || second\";
alert( scopedEval(expr1,scope) );
它会提醒我1
。
范围对象中未定义的变量的唯一问题。这个:
var expr2 = \"third || first || second\";
alert( scopedEval(expr2,scope) );
生成错误“未定义变量ѭ5”。但我希望将所有未知变量解析为undefined
,而不是抛出错误。因此,“第三||第一||第二”应再次屈服于1
。
就我所知,在现代JavaScript中这是不可能的,但是我可能会想念这样的东西。有任何想法吗?
下面是一个示例:http://jsfiddle.net/nCCgT/
解决方法
拦截对不存在的属性的访问是非标准的,并且对于大多数ECMAScript实现而言是不可能的。 JDK附带的Rhino版本似乎提供了此功能,SpiderMonkey可以捕获任意方法调用,但不能捕获常规属性访问。
有一个关于ES Harmony的代理建议,因此已经知道需要这种功能,但是现在,您很不走运。
作为一个非常丑陋的解决方法,您可以扫描
str
查找(潜在)标识符,然后将其添加到scope
中,如下所示:
var toks = str.match(/[A-Za-z_$][\\w$]*/g);
for(var i = 0; i < toks.length; ++i) {
if(!(toks[i] in scope))
scope[toks[i]] = undefined;
}
, 正如其他人指出的那样,除非您至少了解了基本的解析(用于标识符),否则您无法使用当前的JS实现来执行此操作。
我想补充的是:也许正确的答案是什么都不做,让JS失败,因为它现在失败了。您尝试实现的任何解决方案要么太复杂和/或太慢,要么半生不熟。因此,使模板引擎具有如此强大的功能可能不值得付出努力和复杂性。
您可以简单地记录以下内容:“变量/属性引用必须有效。否则,您将得到一个错误。”,并由程序员来承担责任。
, 如果我正确理解了您的问题,那么您应该执行以下操作:
function scopedEval(str,scope) {
var toCheck = str.split(\' || \');
for(var i = 0; i < toCheck.length; ++i){
if(scope[toCheck[i]])
return scope[toCheck[i]];
}
}
可能需要在此处和此处进行一些更好的检查,但是该方法适用于您的小提琴:)
http://jsfiddle.net/nCCgT/1/
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。