2011-12-09 78 views
1

下面你會看到一個JavaScript/jQuery函數我目前使用:JavaScript函數收拾

  var forward = new RegExp('forward'), 
       backward = new RegExp('backward'),    
       left = new RegExp('left'),  
       right = new RegExp('right');     

      if (tweet.message.match(forward)) { 
       console.log('forward'); 
       body.addClass('forward'); 
       bodyRemoveClass();       
      } 

      if (tweet.message.match(backward)) { 
       console.log('backward'); 
       body.addClass('backward'); 
       bodyRemoveClass();       
      } 

      if (tweet.message.match(left)) { 
       console.log('left'); 
       body.addClass('left'); 
       bodyRemoveClass();       
      } 

      if (tweet.message.match(right)) { 
       console.log('right'); 
       body.addClass('right'); 
       bodyRemoveClass();       
      }     

一切都運行得很好,但我不是100%滿意,它的編寫方式。 基本上是做什麼的,檢查一個給定的關鍵字(向前,向後,向左或向右)
都在鳴叫(tweet.message)

我想知道如果有一個簡單/清潔的方式來實現這一點。

很抱歉,但沒有在網上例如...

謝謝

回答

4

有沒有必要使用match()Regexp這裏。你可以用indexOf()做簡單的字符串匹配。然後您可以避免在開始時聲明所有Regexp

 if (tweet.message.indexOf("forward") > -1) { 
      console.log('forward'); 
      body.addClass('forward'); 
      bodyRemoveClass();       
     } 

     if (tweet.message.indexOf("backward") > -1) { 
      console.log('backward'); 
      body.addClass('backward'); 
      bodyRemoveClass();       
     } 

     if (tweet.message.indexOf("left") > -1) { 
      console.log('left'); 
      body.addClass('left'); 
      bodyRemoveClass();       
     } 

     if (tweet.message.indexOf("right") > -1) { 
      console.log('right'); 
      body.addClass('right'); 
      bodyRemoveClass();       
     }    

然而,這是更巧妙地與類數組的形式完成:

// Store your 4 classes in an array 
var classes = ["forward","backward","left","right"]; 
for (var i = 0; i<classes.length; i++) { 

    // Check each class appearing in the message: 
    if (tweet.message.indexOf(classes[i]) > -1) { 
    console.log(classes[i]); 
    body.addClass(classes[i]); 
    bodyRemoveClass();       
    } 
} 
+0

當然重構的是進入4函數調用 – dotjoe

4

您可以使用像這樣的表驅動方式:

var tags = ["forward", "backward", "left", "right"]; 
for (var i = 0; i < tags.length; i++) { 
    if (tweet.message.indexOf(tags[i]) != -1) { 
     body.addClass(tags[i]); 
     bodyRemoveClass(); 
    } 
} 

請記住,任何時候你一遍又一遍地重複相同的邏輯和相同的字符串,你應該找到一種方法來通過遍歷一個表來驅動你的邏輯,把代碼分解成一個通用函數或者某個東西這會阻止你重複一遍又一遍地重複代碼。現在這個軟件開發流行的術語是DRY(不要重複自己)。

也沒有理由用正則表達式測試每個單獨的匹配。雖然在需要時它們可以非常方便,但當需要的時候,.indexOf()會更快。

1

這可通過捕獲匹配短語被急劇縮短:

var match = tweet.message.match(/forward|backward|left|right/g); 
for (var i = 0; match && i < match.length; i++) { 
    console.log(match[i]); 
    body.addClass(match[i]); 
    bodyRemoveClass(); 
} 

在每個那些if塊的不同的唯一事情是要匹配的短語(其是相同的類的名稱被添加)。像這樣的重複可以(而且應該)幾乎總是可以避免的。

+0

這將匹配正則表達式中最大的** 1 **值,而原始函數可以一次匹配所有這些值。 – Aaron

+1

@Aaron - 這不是真的(你看到我的編輯?)。其實,它有*相反的問題。它將循環*全部*匹配,包括重複。 –

+0

糟糕,我正在看原來的'if'語句。也許我應該稍微刷新一下,呃? – Aaron

1
var directions = new Array('forward', 'backward', 'left', 'right'); 
$(directions).each(function() 
{ 
    var regX = new RegExp(this); 
    if (tweet.message.match(regX)) 
    { 
     console.log(this); 
     body.addClass(this); 
     bodyRemoveClass(); 
    } 
}); 
+1

你想在這裏使用jQuery嗎?我不認爲'$(directions).each()'會起作用,$()函數不接受一個普通的字符串數組。也許你的意思是'$ .each(directions,fn)'。 – jfriend00

+0

這兩種語法都可以工作:http://jsfiddle.net/cz5Z9/ – Aaron

+0

請注意,[jquery()文檔頁面](http://api.jquery.com/jQuery/)上沒有任何內容說您可以傳遞該函數的字符串數組。我想我並不是說它不起作用,但它肯定沒有記錄。它確實看起來像'[.each()'這是[文檔](http://api.jquery.com/jQuery.each/)將是一個明智的選擇。 – jfriend00

3
function TweetMatch(classToAdd){ 
    if (tweet.message.match(new RegExp(classToAdd))) { 
     console.log(classToAdd); 
     body.addClass(classToAdd); 
     bodyRemoveClass();       
    } 
} 
TweetMatch('forward'); 
TweetMatch('backward'); 
TweetMatch('left'); 
TweetMatch('right'); 

等(我看到同事提意見已經取得了進展,並提出陣列來迭代...取決於有多少方向你想:-D)