2013-11-01 99 views
29

我試圖在forEach中使用回調方法addToCount而不是匿名函數。但我無法訪問this.count(返回undefined)。將範圍傳遞給for each

function Words(sentence) { 
    this.sentence = sentence; 
    this.count = {}; 
    this.countWords(); 
} 

Words.prototype = { 
    countWords: function() { 
    var words = this.sentence.split(/\W+/); 
    words.forEach(this.addToCount); 
    }, 
    addToCount: function(word) { 
    word = word.toLowerCase(); 
    if (word == '') return; 
    if (word in this.count) 
     this.count[word] += 1; 
    else 
     this.count[word] = 1; 
    } 
} 

我認爲這個問題是範圍。我怎麼能通過thisaddToCount或有任何其他方式使其工作?

+6

words.forEach(this.addToCount,this); – dandavis

+0

完美和簡潔 – rhysclay

回答

53

您需要使用Function#bind的範圍綁定:

words.forEach(this.addToCount.bind(this)); 

注意,這不是在所有的瀏覽器可供選擇:你應該使用一個墊片(如上面提供的鏈接),將其添加到瀏覽器不支持Function#bind


由於dandavis在評論中指出,可以將價值傳遞給Array#forEach作爲回調的背景下:

words.forEach(this.addToCount, this); 
+0

@dystroy事實上,後來'陣列#forEach'不存在IE8要麼... – lonesomeday

+20

的forEach允許您指定這是它的第二個參數,無需使用綁定... – dandavis

+0

@dandavis事實上,謝謝。答案已更新。 – lonesomeday

1

嘗試這樣的事情。我使用了that而不是_this,但我也移動了addToCount,因此它在countWords之內。這將countWords變成一個包含它的閉包。

Words.prototype = { 
    countWords: function() { 
    var that = this, words = this.sentence.split(/\W+/); 
    words.forEach(function(word) { 
     word = word.toLowerCase(); 
     if (word == '') return; 
     if (word in that.count) 
      that.count[word] += 1; 
     else 
      that.count[word] = 1; 
     }); 
    } 
} 
+2

這是我一開始就想到的,我試圖重構它。 – leemour

相關問題