Accessing this in a forEach loop results in undefined
In strict mode if you call a function not through a property reference and without specifying what this
should be, it's undefined.
forEach
(spec | MDN) allows you to say what this
should be, it's the (optional) second argument you pass it:
aGlobalVar.thing.prototype.amethod = function() {
data.forEach(function(d) {
console.log(d);
console.log(this.value);
}, this);
// ^^^^
}
Alternately, arrow functions were added to JavaScript in 2015. Since arrows close over this
, we could use one for this:
aGlobalVar.thing.prototype.amethod = function() {
data.forEach(d => {
console.log(d);
console.log(this.value);
});
}
Since you're using strict mode, when a function is called that isn't a property of an object, this
will have the value undefined
by default (not the global object). You should store its value manually:
var aGlobalVar = {};
(function () {
"use strict";
aGlobalVar.thing = function () {
this.value = "thing";
};
aGlobalVar.thing.prototype.amethod = function () {
var self = this;
data.forEach(function (element) {
console.log(element);
console.log(self.value);
});
};
})();
var rr = new aGlobalVar.thing();
rr.amethod();
Nowadays, with ES2015 you can also use arrow functions, which uses the this
value of the outside function:
function foo() {
let bar = (a, b) => {
return this;
};
return bar();
}
foo.call(Math); // Math
T.J. Crowder's solution of using the second argument of forEach
also works nicely if you don't like the idea of the temporary variable (ES5 code: works in pretty much any browser these days, except IE8-).