我正在写一个GreaseMonkey脚本(使用JQuery),我需要一些由原始页面中的脚本设置的变量,如下所示:
<script type="text/javascript">
var rData = {"20982211":[1,0,1],"20981187":[8,0,4]};
</script>
我从另一个页面获取此元素并尝试评估它,奇怪的是这不起作用:
$.get(link_url, null, function(data) {
alert("1:" + rData);
eval($(data).find("script").text());
alert("2:" + rData);
}
奇怪的是它在firebug控制台上工作(我只是在没有.get的目标页面上直接尝试了eval),当我运行脚本时虽然没有。它在两个警报中都给我“null”。
有什么想法吗?
答案 0 :(得分:4)
EcmaScript 5重新定义了eval
,因此无法将变量绑定添加到封闭的词法环境中。
http://whereswalden.com/2011/01/10/new-es5-strict-mode-support-new-vars-created-by-strict-mode-eval-code-are-local-to-that-code-only/讨论了ES 3下eval
的问题。
但与此同时,eval太强大了。因为内联汇编是针对C或C ++的(至少没有gcc的asm语法要求的信息),所以对eval是eval。在这两种情况下,强大的构造都会抑制许多优化。即使你不关心优化或性能,eval引入和删除绑定的能力使得使用它的代码更难以推理。
...
eval添加绑定的能力更差。这可能使得在运行时之前无法说明名称的含义:
var v;
function test(code)
{
eval(code);
return v;
}
return语句中的v是否表示全局变量?如果不知道代码eval将编译并运行,你就无法知道。如果该代码是“var v = 17;”它指的是一个新变量。如果该代码是“/ * psych!* /”,则它引用全局变量。函数中的eval将取消优化该函数中引用封闭范围中的变量的任何名称。 (并且不要忘记名称测试本身是在一个封闭的范围内:如果函数返回测试而不是v,你不能说该测试是在没有知道代码的情况下引用封闭函数或新变量。)< / p>
您的问题的一个可能的解决方案是使用不同的评估结构,例如, (new Function('alert(rData); ' + ... + '; alert(rData);'))
引入了一个完整的词汇环境。