JavaScript Closure - Eval()并捕获Eval()范围内的变量 [英] JavaScript Closure - Eval() and capturing variables in Eval()'s scope

查看:102
本文介绍了JavaScript Closure - Eval()并捕获Eval()范围内的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是关于JavaScript Closures和Eval()函数。



我有一些看起来像这样的代码,还有一些其他jQuery插件相关的代码taht未示出。如果需要,我可以更多的代码更多的问题。

  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 ,result [0] .length - 3)+,rowData,+ _CurrentDataRowIndex +));
template = template.replace(result [0],AsyncBind !!);
asyncbinder.lastIndex = 0;
}

}

函数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(看异步函数的行返回:+ rowIndex);
}
catch(err){
}
}

},1000);

}

Eval不捕获rowData和_CurrentDataRowIndex,将调用AsynchronousBind函数。 eval如何使用闭包?我想知道为什么rowData和rowIndex参数在AsynchronousBind中未定义。



我知道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 II时忘记更改我的插件中的以下内容:

  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范围是一个有趣的文章。它表明浏览器之间的范围不一致。如果你必须使用eval,你应该小心只有它在全局范围内,并且不要在本地范围中重用全局变量名称,以防在本地求值。



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


My question is regarding JavaScript Closures and the Eval() function.

I have some code that looks like this, there is also some other jQuery plugin related code taht is not shown. I can update the question with more code if needed.

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 is not capturing rowData and _CurrentDataRowIndex, both are undefined when the AsynchronousBind function is called. How does eval work with closures? I am wondering why the rowData and rowIndex arguments are undefined in AsynchronousBind.

Edit:

I am aware of the controversial nature of eval(), however this is for a behind the firewall app, and I'm adding to a plugin we've already written that uses eval to parse templates that contain HTML and JavaScript.

Here is an example of the string being passed into eval():

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

Edit (Fixed):

Realized that when I added rowData and rowItem I I forgot to change the following in my plugin:

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

Should of been:

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

Updating this fixed the undefined reference in the AsyncBind function.

解决方案

Understanding eval scope is an interesting article. It shows that the scope is inconsistent among browsers. If you must use eval, you should be careful to only count on it being in global scope, and don't reuse global variable names in your local scope in case it is evaluated locally.

Better yet, just don't use eval. You probably have other options.

这篇关于JavaScript Closure - Eval()并捕获Eval()范围内的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆