2010-02-12 110 views
1

這是怎麼改進的,因爲它涉及到循環和正則表達式替換?JavaScript:重構循環正則表達式

var properties = { ... }; 
var template = element.innerHTML; 

for (var name in properties) { 
    template = template.replace 
     (new RegExp('\\${' + name + '}', 'gm'), properties[name]); 
} 

element.innerHTML = template; 

有沒有一種方法,我可以得到/\$\{\w+\}/gm的所有比賽,並只使用那些建立一個新的字符串,一次是爲整個操作?

回答

3

JasonHans WRT不與本從性能的角度困擾同意

但是,我會在第一時間不同的寫它:。

element.innerHTML 
    = template.replace(/[$][{](\w+)[}]/g, function(x,y){return properties[y]||x;}) 

有些事情要記住

  1. 如果可能的話,你要避免遍歷創建每次迭代一個RegExp的。編譯它們通常被認爲是昂貴的。或者甚至將其推廣到任何對象創建。雖然不以可讀性/可維護性爲代價。
  2. 如果您要動態創建RegExp,請確保結果是RegExp,否則請參閱#1,因爲您可能會應用它。
+0

我不明白函數(x,y)部分。 RegEx()的第二個參數是模式的標誌,而replace()的第二個參數是返回的新字符串。 – JamesBrownIsDead 2010-02-12 03:44:25

+0

替換的第二個參數可選地是一個轉換函數 – Jimmy 2010-02-12 03:45:41

+0

您可能想要返回屬性[y] || Ÿ;如果你想保留任何未被識別的符號 – Jimmy 2010-02-12 03:48:12

0

看起來效率低下,我認爲你不會做得比這更好。只要你不會取代幾十個令牌,我會驚訝這是否實際上是一個瓶頸。

如果你的分析器沒有發現這是一個瓶頸,我絕對不會花時間重寫它。如果沒有其他的東西,它比其他想法更具可讀性,並且最終它可能同樣快。

1

我會咬;-)

var properties = { ... }; 
var template = element.innerHTML; 
element.innerHTML = template.replace (
    RegExp ('\\$\\{(' + getTags (properties).join ('|') +')\\}'), 
    function (m0, tag) {return properties[tag];}); 

function getTags (obj) { 
    var tags = []; 
    for (var t in obj) 
    hasOwnProperty (t) && tags.push (t); 
    return tags; 
} 

通過屬性的標籤仍然環路(在getTags通話),但只創建一個 RegExp對象和掃描模板只有一次。

注意,在屬性標籤名稱不能包含特殊字符的正則表達式(如,或(等)。

我與Jason同意雖然,也許不值得的努力,除非有很多的標籤或模板是非常大的