2011-09-21 62 views
3

我的問題是關於JavaScript閉包和Eval()函數。JavaScript關閉 - 評估()和捕獲變量在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(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); 

} 

評估和演示沒有捕捉rowData和_CurrentDataRowIndex,當AsynchronousBind函數被調用這兩個是不確定的。 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 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函數中未定義的引用。

+0

如果問題包含「'eval'」,那麼答案是:**不要**。 – Quentin

+6

看起來你正在嘗試使用'eval',因爲你只知道如何使用點符號來訪問屬性。請改爲了解[方括號表示法](http://www.dev-archive.net/articles/js-dot-notation/)。 – Quentin

+1

提示:請勿使用eval。它不需要你想做的事情。此外,您傳遞的代碼無效:沒有起始括號。 –

回答

5

Understanding eval scope是一篇有趣的文章。它表明範圍在瀏覽器中不一致。如果您必須使用eval,那麼您應該小心只指望它在全局範圍內,並且不要在本地範圍內重用全局變量名稱,以免在本地進行評估。

更好的是,不要使用eval。你可能有其他選擇。

+3

感謝您的文章鏈接 – dmck