在 Eval 中设置变量 (JavaScript)

发布于 2024-11-05 09:58:55 字数 515 浏览 0 评论 0原文

我正在编写一个 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”。

有什么想法吗?

i'm writing a GreaseMonkey script (using JQuery), and i need some variables that are set by a script in the original page, like this:

<script type="text/javascript"> 
    var rData = {"20982211":[1,0,1],"20981187":[8,0,4]};
</script>

I fetch this element from another page and try to eval it, put strangely this doesn't work:

$.get(link_url, null, function(data) {
   alert("1:" + rData);
   eval($(data).find("script").text());
   alert("2:" + rData);
}

The strange thing is on the firebug console it works (i just tried the eval directly on the targetpage without the .get), when i run the script though it doesn't. It gives me "null" in both alerts.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我鬧 2024-11-12 09:58:55

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 对于 JavaScript 也是如此。在这两种情况下,强大的构造都会抑制许多优化。即使您不关心优化或性能,eval 引入和删除绑定的能力也会使使用它的代码更难以推理。

...

eval 添加绑定的能力较差。这使得在运行时之前无法说出名称所指的内容:

var v;
function test(code)
{
  eval(code);
  return v;
}

return语句中的v是否表示全局变量?如果不知道代码 eval 将编译和运行,您就无法知道。如果该代码是“var v = 17;”它引用一个新变量。如果该代码是“/* psych! */”,则它指的是全局变量。函数中的 eval 将取消优化该函数中引用封闭范围内的变量的任何名称。 (并且不要忘记名称 test 本身位于封闭范围内:如果函数返回 test 而不是 v,则在不知道代码的情况下无法判断该测试是引用封闭函数还是新变量。)< /p>

)解决您的问题的可能方法是使用不同的评估构造,例如 (new Function('alert(rData); ' + ... + ';alert(rData);')) 引入了完整的词汇环境。

EcmaScript 5 redefined eval so that it cannot add variable bindings to the enclosing lexical environment.

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/ talks about the problems with eval under ES 3.

Yet at the same time, eval is too powerful. As inline assembly is to C or C++ (at least without the information gcc‘s asm syntax requires), so is eval to JavaScript. In both instances a powerful construct inhibits many optimizations. Even if you don’t care about optimizations or performance, eval‘s ability to introduce and delete bindings makes code that uses it much harder to reason about.

...

eval‘s ability to add bindings is worse. This can make it impossible to say what a name refers to until runtime:

var v;
function test(code)
{
  eval(code);
  return v;
}

Does the v in the return statement mean the global variable? You can’t know without knowing the code eval will compile and run. If that code is "var v = 17;" it refers to a new variable. If that code is "/* psych! */" it refers to the global variable. eval in a function will deoptimize any name in that function which refers to a variable in an enclosing scope. (And don’t forget that the name test itself is in an enclosing scope: if the function returned test instead of v, you couldn’t say whether that test referred to the enclosing function or to a new variable without knowing code.)

One possible solution to your problem is to use a different evaluation construct, e.g. (new Function('alert(rData); ' + ... + '; alert(rData);')) introduces a complete lexical environment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文