[問題] 這個傳遞資料錯誤的原理為何?

看板Ajax作者 (阿達)時間7年前 (2017/08/22 23:08), 7年前編輯推噓1(1012)
留言13則, 3人參與, 最新討論串1/1
各位大大好~ 小弟研究了半天找到了不會出錯的寫法 但是 會出錯的寫法我怎麼想都想不通它是如何產生那樣的錯誤結果 想來請教各位 以下是我完整的測試網頁 ====================== <html> <head> <meta http-equiv="Content-Type" content="text/html" charset="utf-8"> <title>Test</title> <style type="text/css"> .myBtn {width: 150px; padding: 4px; margin: 4px;} </style> <script type="text/javascript" src="jquery-1.11.0.min.js"></script> <script type="text/javascript"> // 按鈕templete var tpl_btn = '<button class="myBtn"></button>'; // 文句庫 var txtLibrary = { '0001': 'Allen', '0002': 'Bob', '0003': 'C' }; // 頁面ready初始化 $(document).ready(function() { setWindow([ {tid: '0001', func: A_FUNC}, {tid: '0002', func: B_FUNC}, {tid: '0003', func: C_FUNC} ]); }); // 產生畫面 function setWindow(infoArray) { var buttons = []; // 不會出錯 $(infoArray).each(function(i, info) { var _label = txtLibrary[info.tid], _func = function(e) { info.func(true, _label); }; buttons.push({label: _label, func: _func}); }); // 會出錯 /* for (var i in infoArray) { var info = infoArray[i], _label = txtLibrary[info.tid], _func = function(e) { info.func(true, _label); }; buttons.push({label: _label, func: _func}); } */ setButtons(buttons); } // 產生按鈕 function setButtons(buttons) { var $btnArea = $('#btnArea'); for (var i = 0; i < buttons.length; i++) { var btn = buttons[i]; $btnArea.append($(tpl_btn) .html(btn.label).on('click', btn.func) ); } } function A_FUNC(isDebug, name) { alert(name + ' run A ' + (isDebug ? 'DEBUG' : 'FUNCTION')); } function B_FUNC(isDebug, name) { alert(name + ' run B ' + (isDebug ? 'DEBUG' : 'FUNCTION')); } function C_FUNC(isDebug, name) { alert(name + ' run C ' + (isDebug ? 'DEBUG' : 'FUNCTION')); } </script> </head> <body> <div id="btnArea"></div> </body> </html> ====================== 正常得到的結果是 按 Allen 這個 button 顯示 "Allen run A DEBUG" 按 Bob 這個 button 顯示 "Bob run B DEBUG" 按 C 這個 button 顯示 "C run C DEBUG" 而錯誤的那個寫法會得到 按 Allen 這個 button 顯示 "C run C DEBUG" 按 Bob 這個 button 顯示 "C run C DEBUG" 按 C 這個 button 顯示 "C run C DEBUG" 是如何錯的呢? 感謝~~~ -- . ______ ◥█◣▲◢█◤ ◥ ◥GRAVEYARD. \◤◥█◤◥◤ ◤ ' \ BILE DEMON'◥◥◤◤ ◢▌  ̄ ̄ ̄ ̄ ̄ ̄ █▌ ◣ ◥▌ ◢◢//\ ●● ◥◥ ◤◥ ◤◤◣◣ ▃▇ ▆◣▂◢▂▅█▄ USHER -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.224.50.35 ※ 文章網址: https://www.ptt.cc/bbs/Ajax/M.1503414498.A.94D.html ※ 編輯: usherII (61.224.50.35), 08/22/2017 23:11:06 ※ 編輯: usherII (61.224.50.35), 08/22/2017 23:16:36

08/22 23:53, , 1F
正確的 _func 歸屬在各自 function 下,各自獨立,錯誤
08/22 23:53, 1F

08/22 23:53, , 2F
的歸屬在 setWindow 下,function 為傳址,後續定義蓋
08/22 23:53, 2F

08/22 23:53, , 3F
了前面的
08/22 23:53, 3F

08/23 00:37, , 4F
就結果看是如此,問題是for裡面的新var為何會被覆蓋?
08/23 00:37, 4F

08/23 00:39, , 5F
而且有趣的是,錯誤寫法的button其label顯示沒錯
08/23 00:39, 5F

08/23 00:40, , 6F
只錯alert出來的部分
08/23 00:40, 6F

08/23 01:02, , 7F
就結果來看for寫法的info參考了infoArray且i也是參考
08/23 01:02, 7F

08/23 01:04, , 8F
那如果堅持要用for 我該如何準確傳遞個別info ?
08/23 01:04, 8F

08/23 01:56, , 9F
因為js裡面變數只有function scope,for block不會有獨立的
08/23 01:56, 9F

08/23 02:00, , 10F
scope,所以沒有新的var,都是同一個
08/23 02:00, 10F

08/23 02:07, , 11F
需要留著之後用的變數就要放在多一層function中
08/23 02:07, 11F

08/23 02:09, , 12F
_func = function() ←裡面要多存一份info和_label
08/23 02:09, 12F

08/23 09:12, , 13F
感謝樓上~ 變數是function scope就打通了!
08/23 09:12, 13F
文章代碼(AID): #1Pd4ZYbD (Ajax)
文章代碼(AID): #1Pd4ZYbD (Ajax)