javascript传递eval变量

Posted

技术标签:

【中文标题】javascript传递eval变量【英文标题】:javascript pass eval variables 【发布时间】:2012-12-16 22:36:19 【问题描述】:

我有 eval 函数,它需要从 php 执行 javascript。但我需要传递元素,所以我可以将鼠标放在用户点击的链接上的提示上。

var globalEval = function globalEval(src, element) 
        if (window.execScript) 
            window.execScript(src);
            return;
        
        var fn = function(element) 
            window.eval.call(window,src);
        ;
        fn(element);
    ;

我使用以下方式传递$(this)元素

globalEval(js_code, $(this));
// js_code is = alert(element);

我得到未定义元素的错误,它在globalEval(); 中定义我该如何解决这个问题?

【问题讨论】:

如果我假设src 始终是一个字符串是正确的,如果你这样做window.eval.call(window,'(function (element) '+src+')')(element); 会发生什么? @PaulS。好的,我会尝试并回帖。 【参考方案1】:

这是一个范围问题,因为全局 eval 没有调用与变量 element 相同范围内的代码。如果你必须使用eval,即使eval is evil,你必须以一种允许你在你想要的环境中调用你的代码的方式来做。一种方法是将其包装为匿名函数,您可以为选择的环境变量提供参数。

例如

window.eval.call(window,'(function (element) '+src+')')(element);

这意味着src 字符串被解析但未被eval 调用,因为它返回一个匿名函数。然后您调用它,传递您的数据,在本例中为 element

var element = document.body, src = 'console.log(element.tagName)'; 测试它,你会看到它记录"BODY"。请注意,如果您想以这种方式设置全局变量(或函数),它们必须显式声明为全局变量(window.foobar = ...),否则它们将在匿名函数完成后被 GCd。

【讨论】:

为什么不只是本地的eval(src),它会选择element @Esailija 因为我喜欢把事情过度复杂化。不,我的回答方式意味着您通过传递变量来指定环境并保护您当前的环境(因为函数是 ByVal,诸如 element = otherElm 之类的更改不会影响您调用它的位置)而本地 eval(src) 将使用当前环境。它还为您提供了有关调用它的其他选项(例如 var-ing it / using .call)。我并不是说eval 永远“安全”,但至少这种方式意味着你可以在你想要的环境中调用(假设src 是有效的JavaScript)。 @PaulS。非常感谢。这现在很好用:)。顺便说一句,这也可以工作 window.execScript('(function (element) '+src+')')(element); ? 您应该改用Function constructor:它可以更好地报告(语法)错误。 @geocar +1 因为我同意,但这样做不涉及eval,这不是 OP 的问题。【参考方案2】:

如果全部您想要在评估某些代码时设置this,请尝试:

// Code you want to evaluate
var code = 'return this.whatever'

// What you want "this" bound to:
var that =  whatever: 69 

// Now do this:
var result = new Function(code).call(that)

使用 Function 构造函数意味着你会得到你所期望的;全球评估带来了很多包袱,其中一些可能会让您感到惊讶。如果你不需要它最好避免它。

现在,如果您真的想将其命名为 element,Function constructor 也可以这样做:

code = 'alert(element)'
var use_element = 69
result = new Function("element", code).call(this, use_element)

【讨论】:

我喜欢你的建议。只是想知道旧浏览器是否支持它,以及来自 php 的任何 javascript 动态代码是否可以正常执行而没有错误? @Basit - 有关浏览器兼容性,请参阅 aptana.com/reference/api/Function.html。 PHP 没有进入它,你可以简单地做这样的事情:result = new Function("element", <?= json_encode($code) ?>).call(this, use_element) 如果你愿意。【参考方案3】:

如果回调函数在同一个 dom 中,则在 eval 之前设置一个全局变量作为 repo,这将保留该变量。然后在你要调用的函数中使用全局变量。

var response_repo;
function someFunc($callback)
 ....
 success: function(result) 
            response_repo = result;
            eval($callback+'();');
        ,
 ....
 


 callBackFunc()
  $data=response_repo;
 

【讨论】:

以上是关于javascript传递eval变量的主要内容,如果未能解决你的问题,请参考以下文章

js中eval()的使用说明

从 bash 变量为 Erlang erl 传递 -eval 失败

利用eval()来“欺骗”JavaScript词法作用域

JavaScript eval

javaScript 工作必知 eval 的使用

JavaScript强大的 eval() 函数