Passing scope to forEach
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?
Solution 1:
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);
Solution 2:
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;
});
}
}