2013-11-01 13 views
29

Sto tentando di utilizzare un metodo di richiamata addToCount anziché la funzione anonima in forEach. Ma non riesco ad accedere a this.count (restituisce undefined).Passa lo scope a forEach

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; 
    } 
} 

Penso che il problema sia lo scopo. Come posso passare this a addToCount o esiste un altro modo per farlo funzionare?

+6

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

+0

Perfetto & succinto – rhysclay

risposta

53

è necessario utilizzare Function#bind per associare un campo di applicazione:

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

Si noti che questo non è disponibile in tutti i browser: si consiglia di utilizzare uno spessore (come previsto nel link qui sotto) per aggiungerlo nei browser che non supportano Function#bind.


Come dandavis sottolinea nei commenti, è possibile passare un valore al Array#forEach come il contesto per la richiamata:

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

@dystroy Infatti, ma in questo caso "Array # forEach" non esiste in IE8 ... – lonesomeday

+20

forEach consente di specificare questo come secondo argomento, non è necessario utilizzare bind ... – dandavis

+0

@dandavis Infatti, grazie. Risposta aggiornata – lonesomeday

1

provare qualcosa di simile. Ho usato that anziché _this ma ho spostato anche addToCount quindi è all'interno di countWords. Questo trasforma countWords in una chiusura che contiene quello.

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

Questo è quello che ho avuto all'inizio e sto cercando di rifattorizzarlo. – leemour

Problemi correlati