JavaScript闭包 - Eval()和捕获Eval()作用域中的变量

3
我的问题涉及JavaScript闭包和Eval()函数。
我有一些代码看起来像这样,还有一些其他的jQuery插件相关的代码没有展示出来。如果需要,我可以更新问题并提供更多的代码。
var _CurrentDataRowIndex = 1;

function LoadParsedRowTemplate(rowData, type) {

    var result;
    var asyncbinder = /&\{[\S\s]*?}&/g;

        while ((result = asyncbinder.exec(template)) != null) {
            replacement = eval("$.fn.ScreenSetup." + result[0].substring(2, result[0].length - 3) + ", rowData, " + _CurrentDataRowIndex + ")");
            template = template.replace(result[0], "AsyncBind!!");
            asyncbinder.lastIndex = 0;
        }

}

function AsynchronousBind(asyncFunc, args, rowData, rowIndex) {

    var watchTimer;

    asyncFunc.apply(this, Array.prototype.slice.call(args.FunctionArgs, 0));

    watchTimer = setInterval(function () {

        if (args.finished) {
            clearTimeout(watchTimer);
        }
        else {
            try {
                console.log("watching the async function for a return on row: " + rowIndex);
            }
            catch (err) {
            }
        }

    }, 1000);

}

当异步绑定函数被调用时,eval无法捕获rowData和_CurrentDataRowIndex,两者都为未定义。闭包与eval如何配合工作呢?我想知道为什么AsynchronousBind中的rowData和rowIndex参数是未定义的。

编辑:

我知道eval()存在争议性,但这是为了一个内部应用程序,并且我正在添加到我们已经编写的插件中,该插件使用eval解析包含HTML和JavaScript的模板。

以下是传递给eval()的字符串示例:

 "$.fn.ScreenSetup.AsyncBind( _CurrentDataRow.isPromotionAvailable, {
     'FunctionArgs': {'doAsync' : true, 
                      'finished' : false}, 
      'Property': 'isPromotionAvailable()', 
      'ControlType': 'TextBox', 
      'ControlIdPrefix': 'promoAvail'}, rowData, 3)"

编辑(已修复):

我意识到当我添加rowData和rowItem时,我忘记在我的插件中更改以下内容:

var asyncMethods = {
    AsyncBind: function (func, args) { return AsynchronousBind(func, args) }
}

应该是:

var asyncMethods = {
    AsyncBind: function (func, args, rowData, rowIndex) { return AsynchronousBind(func, args, rowData, rowIndex) }
}

更新这个问题修复了AsyncBind函数中的未定义引用。

如果问题涉及“eval”,那么答案就是:不要使用 - Quentin
6
看起来你正在尝试使用 eval,因为你只知道使用点符号访问属性。相反,学习一下方括号符号表示法 - Quentin
1
提示:不要使用eval。它对你想做的事情没有必要。此外,你传递的代码无效:没有起始括号。 - goto-bus-stop
2
@Quentin 我知道方括号表示法,但在这种情况下,我正在解析包含HTML和JavaScript的模板,它们位于特殊标记之间,因此我需要使用eval()。 - dmck
1个回答

6

理解eval作用域是一篇有趣的文章。它展示了各浏览器之间作用域的不一致性。如果你必须使用eval,你应该小心地只依赖于全局作用域,并且在本地作用域中不要重复使用全局变量名称,以防在本地进行评估。

更好的选择是,不要使用eval。你可能有其他选项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接