Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing scope to forEach

Tags:

javascript

I'm trying to use a callback method addToCount instead of anonymous function in forEach. But I can't access this.count in it (returns undefined).

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

I think the problem is the scope. How can I pass this to addToCount or is there any other way to make it work?

like image 857
leemour Avatar asked Nov 01 '13 19:11

leemour


2 Answers

You need to use Function#bind to bind a scope:

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

Note that this is not available in all browsers: you should use a shim (as provided in the link above) to add it in the browsers that don't support Function#bind.


As dandavis points out in the comments, you can pass a value to Array#forEach as the context for the callback:

words.forEach(this.addToCount, this); 
like image 105
lonesomeday Avatar answered Oct 01 '22 14:10

lonesomeday


Try something like this. I've used that rather than _this but also I've moved addToCount so it's inside countWords. That turns countWords into a closure containing that.

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;       });   } } 
like image 25
NickM Avatar answered Oct 01 '22 12:10

NickM