Re: [問題] javascript執行問題

看板Web_Design作者 (AwA)時間14年前 (2010/05/14 06:45), 編輯推噓1(101)
留言2則, 2人參與, 最新討論串2/2 (看更多)
※ 引述《shomingchang ( )》之銘言: : <script> : var calculate_sqrt_patt=/\(Math.sqrt\(\d+\)\)/g; : var metPatt; : calculate_sqrt_patt.compile(calculate_sqrt_patt); : var CurrentResult="(Math.sqrt(121))+(Math.sqrt(25))+(Math.sqrt(81))+ : (Math.sqrt(144))+(Math.sqrt(169))+(Math.sqrt(49))"; : : while((metPatt=calculate_sqrt_patt.exec(CurrentResult))!=null) : { : var replaceString; : var str=metPatt.toString(); : alert(CurrentResult+":\n"+str); : replaceString=eval(str).toString(); : CurrentResult=CurrentResult.replace(str,replaceString); : } 在Bugzilla裡面,這個問題(其實不是Bug)已經存在將近10年了! 看了一下討論串,好像每年至少都會有一兩個人回報這個現象! 簡單來說,就是Regular Expression裡面的g(global)這個選項有被開啟的話, 這個RegExp物件裡的lastIndex就會將每次parse時的字串位置記錄下來。 這樣會使下次在使用這個RegExp物件搜尋字串時(不限是否相同字串),不會重複搜尋。 注意,RegExp裡的lastIndex並不會因為丟進新的String就重頭開始搜尋! 用原PO附的程式碼舉例來說, 第一輪RegExp執行exec()之後,matPatt會得到"(Math.sqrt(121))", 然後calculate_sqrt_patt.lastIndex會等於16,也就是(Math.sqrt(121))最後的)位置。 由於原PO將(Math.sqrt(121))替換成執行結果11,造成字串被改變, 所以calculate_sqrt_patt.lastIndex就會改指向"(Math.sqrt(25))"的5的位置, "(Math.sqrt(25))"就被忽略掉了。程式繼續執行下去就會有跳一格資料的感覺。 總的來說,解決辦法有兩種: 1) 將RegExp物件的g參數去掉,這樣不會記錄lastIndex,這值永遠是0。 2) 每一輪迴圈都執行:calculate_sqrt_patt.lastIndex = 0; 把lastIndex歸零,就會重頭開始。 不過第一種似乎比較推薦 :) -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.113.247.149

05/14 06:46, , 1F
補充:討論串在Bugzilla Bug編號 98409 裡面
05/14 06:46, 1F

05/14 14:36, , 2F
恩 謝謝
05/14 14:36, 2F
文章代碼(AID): #1Bx84B07 (Web_Design)
文章代碼(AID): #1Bx84B07 (Web_Design)