站長(zhǎng)資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        瀏覽器中的正則表達(dá)式陷阱說明

        在本章開始前 我要引入一個(gè)例子 來說明這種不徹底的 變態(tài)的優(yōu)化 到底合理還是不合理…

        c# 中的 字符串直接量 做的優(yōu)化 就非常徹底…這種優(yōu)化我們應(yīng)該是歡迎的…

         string str=”franky”;

        string str2=”franky”;

        在內(nèi)存中 只有一份 字符串對(duì)象 而str和str2 具備相同的一份引用. 很明顯 這非常合理.

        string n = “franky”,  n2 = “franky”;
        Response.Write((Object.ReferenceEquals(n,n2)).ToString());//True.

        那么 一些特殊情況下  有些瀏覽器 為正則表達(dá)式直接量也做了類似的優(yōu)化.

        alert(/d/==/d/);//所有瀏覽器都是false 這很合理 因?yàn)檎齽t表達(dá)式直接量 同 [] 數(shù)組直接量 {}對(duì)象直接量一樣 都是引用類型 

        我們?cè)倏纯茨男┣闆r下哪些瀏覽器做了優(yōu)化

            function f2() {
                return /d/;
            }

               alert(f2() == f2());

        //這里的結(jié)果就有不同了

        ie6 7 8  opear10 safari4 都返回false  (我虛擬機(jī)里safari3壞了沒做測(cè)試.如果誰有 幫忙測(cè)下告訴我結(jié)果.謝謝 我估計(jì)safari3 會(huì)返回true.原因是 maxthon3用的引擎貌似就是safari3 的) 

        但是

        firefox 2.0 3.0+ 3.5 3.6  chrome 4 5 opear9  maxthon3 demo版  使用webkit引擎下 都返回true

        有趣的地方在于 opera9 做了優(yōu)化 而opera10 取消了這種優(yōu)化. 看來至少opera團(tuán)隊(duì)認(rèn)為這種優(yōu)化時(shí)不恰當(dāng)?shù)?#8230;(變相支持了我的觀點(diǎn).)

         

        看到這里 你也許會(huì)奇怪 是不是 bug而不是所謂優(yōu)化啊? 也許是閉包對(duì)象 出了什么問題或者 是 函數(shù)對(duì)象上的某些bug引起的?

        那么我們看看下面的例子:

        for (var i = 0; i < 10; i++) document.writeln(/d/g.test(” + i));

        不同瀏覽器 輸出結(jié)果的 差異 完全符合上面 是否做優(yōu)化的分類.

        即沒有 做優(yōu)化的瀏覽器 一律返回true 而作了優(yōu)化的瀏覽器 則是 true false true false 交替的結(jié)果.

        我們這里只是一個(gè) 循環(huán) ..js中的循環(huán)沒有獨(dú)立的作用域 更不會(huì)產(chǎn)生閉包對(duì)象 那么可以肯定 引起這個(gè)怪異問題的 根本原因就是某些瀏覽器自作聰明的優(yōu)化.

        可能大家不太理解 test的結(jié)果 差異來自哪里…  答案是 test 同 exec 一樣 如果 直接量后面有/g  .設(shè)置了 global全局查找參數(shù) 的話 那么 同一個(gè)test對(duì)象 會(huì)記錄上次 匹配字符的索引位置.下次再 匹配時(shí) 會(huì)從這個(gè)位置開始..如果沒有 則 匹配索引<0 下次在此匹配時(shí) 就仍然從0位置字符開始.

        所以上面這個(gè)測(cè)試 使用 exec 也是可以的.

        那么 這里 如何避免瀏覽器差異呢? 簡(jiǎn)單的辦法 去掉/g即可

        這里我們?yōu)榱硕惚芟葳?就要 記得一個(gè)約定.  請(qǐng)盡量不要使用 一個(gè)正則直接量 在函數(shù)體內(nèi) 或 循環(huán)內(nèi). 如果一定要如此 請(qǐng)使用new RegExp(‘d’,g);這種.

        對(duì)于exec 盡量用 string.match代替. 因?yàn)閙atch 強(qiáng)制你依靠是否有 /g 來全局查找..不會(huì)產(chǎn)生歧義.

        對(duì)于test 如果是循環(huán)內(nèi) 也可以考慮  var reg=/d/; //這里要吧/g去掉..請(qǐng)不要忘記哦

        for (var i = 0; i < 10; i++) document.writeln(reg.test(” + i));

        事實(shí)上這樣用是最合理的辦法 .原因是 這里我們只產(chǎn)生一個(gè)正則對(duì)象 并反復(fù)使用他.. 本質(zhì)上也是為了優(yōu)化。但是我們避開了 瀏覽器自己的優(yōu)化差異 導(dǎo)致的不同結(jié)果.

        最后我們發(fā)現(xiàn) 所謂陷阱 發(fā)生主要是 /g使用不當(dāng).無論是 exec 還是test都是如此  如果合理使用/g 無論瀏覽器是否存在變態(tài)的優(yōu)化. 執(zhí)行結(jié)果都將是正確的…唯一的區(qū)別 只在于 做了優(yōu)化的瀏覽器 不需要反復(fù)產(chǎn)生一個(gè) 正則對(duì)象然后再垃圾回收 再產(chǎn)生一個(gè)正則對(duì)象….如此反復(fù)而已…

        那么我們發(fā)現(xiàn) 遵守上面幾個(gè)原則的話 這種問題 也都避免了…

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
        主站蜘蛛池模板: 秋霞久久国产精品电影院| 日本一区二区三区精品中文字幕| 国产精品视频一区二区噜噜| 欧美精品一二区| 日本一区精品久久久久影院 | 国产成人毛片亚洲精品| 国产精品人成在线播放新网站| 亚洲一级Av无码毛片久久精品| 国产在线精品福利大全| 亚洲国产精品久久久久久| 国精品午夜福利视频不卡| 亚洲AV无码成人精品区天堂| 污污网站国产精品白丝袜| 精品中文高清欧美| 国产精品青青在线观看爽香蕉 | 亚洲欧洲久久久精品| 国产三级精品三级在线观看专1| 最新国产精品亚洲| 国产日韩一区在线精品欧美玲| 精品国产福利一区二区| 亚洲国产精品18久久久久久 | 亚洲韩国精品无码一区二区三区 | 在线精品国产一区二区| 国产精品186在线观看在线播放| 久久91精品国产91久久小草| WWW国产精品内射老师| 国产精品无码成人午夜电影| 久久九九精品99国产精品| 无码国产精品一区二区免费16| 亚洲人成精品久久久久| 亚洲欧美国产∧v精品综合网| 久久e热在这里只有国产中文精品99 | 凹凸69堂国产成人精品视频| 国自产偷精品不卡在线| 欧美精品亚洲精品日韩传电影| 亚洲AV永久无码精品| 欧美性videos高清精品| 国产99视频精品免视看7| 华人亚洲欧美精品国产| 69堂午夜精品视频在线| 国产成人AV无码精品|