問題來自一位叫小白的同事的疑問,問題以下:正則表達式
var str = '[img_/storage/uploads/2016/1465955105.2148.jpg]'; str = str.replace(/\[img_(\S*)\]/g,"<img src='$1' class='chatImg'>");
或者跨域
var str = '[img_/storage/uploads/2016/1465955105.2148.jpg]'; var name = new RegExp("\[img_(\S*)\]",'g'); str = str.replace(name,"<img src='$1' class='chatImg'>");
正則大神現身,這兩種寫法有什麼區別?爲何結果不一樣?瀏覽器
不管怎麼試都有問題,首先上面的正則有點問題,咱們調整一下:閉包
var str = '[img_/storage/uploads/2016/1465955105.2148.jpg]'; var aa = /\[img_(\S*)\]/g; var bb = new RegExp("\\[img_(\\S\*)\\]",'g'); var cc = "<img src='$1' class='chatImg'>"; //方法1 str.replace(aa, cc); //方法2 str.replace(bb, cc);
結果同樣了,這就是一個正則的問題
原本到這裏就完了,但是小白仍是很執着的,爲何他寫的不行,他再次用正確的正則來測試,代碼貼出來以下:測試
顯然他以前也測試過,只是用 replace 來作驗證的,我測試也不通,就測試 new RegExp得出的結果是否同樣了,不知不覺,改了變量名來測試了,重複的東西別我提取,專門測試不同的地方,反而避免了這個 name 變量名的問題網站
var str = '[img_/storage/uploads/2016/1465955105.2148.jpg]'; var name = new RegExp("\\[img_(\\S\*)\\]",'g'); str = str.replace(name,"<img src='$1' class='chatImg'>");
怎麼會仍是不行,此次正則絕對沒錯了,都測試經過了url
結果此次在控制檯測試,確實不經過,咦爲何?spa
小白得出個暫時的結論:var 正則,不能用 name 來命名調試
這就奇怪了,哪有這樣的道理,你覺得你是誰啊,你又不是關鍵字、保留字,還不讓做爲變量用了,憑什麼不讓命名?還限制正則不讓用?code
沒有這樣的道理,這時我才注意到 name 這個名字的特別處,我有個印象,name 是做爲 window 的一個屬性在使用,做爲當前窗口(tab 頁)的名稱,即便網站都跳轉走了,只要當前窗口沒變,那麼 name 值一直存在,不跟 url 相關,這能夠用來爲跨域來用
這裏難道有問題,因而專注測試 name 這個特殊變量:
var name = new RegExp("\\[img_(\\S\*)\\]",'g'); //輸出 name //"/\[img_(\S*)\]/g" 而 var bb = new RegExp("\\[img_(\\S\*)\\]",'g'); //輸出 bb //\[img_(\S*)\]/g
在控制檯下調試,不細看就錯過去了,差了分號,上面的結果實際變成字符串了
奇怪啊,正則不行,變量類型都變了,我試試其餘數據類型,
也是不行,但在閉包裏能夠了,這是 name 這個值做爲特定屬性,被限制爲「強數據類型」了,js 中一直沒有此概念,普通變量,我想什麼類型就什麼類型,賦值就能夠了,這裏一個大坑,真是不可料想,變量類型不可變(自動轉爲 String 類型)
還有其餘變量是這樣的麼,呵呵,這根本無法預料,這個瀏覽器用這個名字,鬼知道那麼多瀏覽器,誰會不會偶爾又用了一個變量名字呢,他又有什麼限制呢!!!
舊事重提,一直說盡可能避免使用全局變量,今天又上了一課,若是不遵照,終會摔跟頭,並且死都不知道怎麼死的,另外變量名稱真的不是隨便用的,良好的命名規範,能避免出現這種狀況,和非意義的變量名aa, bb相比,name明顯有具體指代,指某名稱,做爲一個正則表達式的值來用,確有不合理之處,名字不能夠隨便叫啊。不過也正由於如此,發現這個變量名原來還有這種限制。
咱們當前的開發,幾乎不存在使用全局變量的狀況了,全都使用閉包封裝了,能避免變量被污染(或者出現上面變量類型被限制的狀況),但個別狀況,簡單頁面,仍是存在不適用閉包把本身的變量所有包裝的狀況,這是極可能出問題
因此只要能用閉包包裝,儘可能把本身的邏輯包裝起來,省得再出現相似的詭異問題