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-).

Tags:

Javascript