最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavaScript Closure - Eval() and capturing variables in Eval()'s scope - Stack Overflow

programmeradmin1浏览0评论

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.

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.

Share Improve this question edited Sep 22, 2011 at 1:32 dmck asked Sep 21, 2011 at 16:33 dmckdmck 7,8617 gold badges45 silver badges79 bronze badges 4
  • If the question includes "eval" then the answer is: don't. – Quentin Commented Sep 21, 2011 at 16:35
  • 6 It looks like you are trying to use eval because you only know how to access properties using dot notation. Learn about square bracket notation instead. – Quentin Commented Sep 21, 2011 at 16:36
  • 1 Tip: Don't use eval. It's not needed for what you want to do. Besides, the code you're passing is invalid: there's no starting bracket. – goto-bus-stop Commented Sep 21, 2011 at 16:36
  • 2 @Quentin I'm aware of the square bracket notation, however in this case I am parsing a template that contains HTML and JavaScript bined between special tags, so I need eval(). – dmck Commented Sep 21, 2011 at 17:34
Add a ment  | 

1 Answer 1

Reset to default 6

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.

发布评论

评论列表(0)

  1. 暂无评论