Sir Isaac Newton laid out the basics of the Relativity theory in the 17th century. Einstein later extended his work with his Special Theory of Relativity, unknowingly providing numerous sci-fi authors with a free plot. The faster you go through space, the slower you go through time, you see, so time is relative.
Do you know what else is relative? ‘This’ context in JavaScript…
Let’s go through a really simple Script Include:
var TestyMcTestface = Class.create();
TestyMcTestface.prototype = {
initialize: function() {
},
logger: function(number) {
gs.info('Simple test' + number);
},
process: function() {
var someArray = [1, 2, 3];
someArray.forEach(function(element) {
this.logger(element);
});
},
type: 'TestyMcTestface'
};
We have the logger method, which, oddly enough, logs things. It also takes a number and sticks it to the thing it logs. Then we have the main one – the process method, imitating actual business logic. Inside we have some array literal, so literally someArray. It probably won’t be literal like that in real life, but a bucket of actual data we got somehow that we want to iterate over.
It looks like a simple enough concept – we take an element from the array and call the logger while passing the element as an argument. And it fails miserably without showing any error or message. Usually, this is where we embark on a multiple-hour-long quest to find the bug where it isn’t. Where it actually is, is right before our eyes.
Any methods we create inside a Script Include will have a pretty accurate idea of what ‘this’ means when we make them call one another. For all of them, ‘this’ means the actual class where they were defined. On the other hand, JS array methods like to be a bit more independent, at least the ones that require a callback function to operate. Like many other things in JavaScript, it’s all down to scope again. For the callback function of the .forEach() method, ‘this’ means the object where it was defined, so the .forEach() method itself (and yes, functions are actually objects in JavaScript, that’s the beauty of it). The callback then tries to call the logger method from the wrong ‘this’, and all it gets from that is ‘undefined’ result.
So, to make this work, we need to point the callback to the correct ‘this’. Or, in other words, bind the correct ‘this’ to it:
someArray.forEach(function(element) {
this.logger(element);
}.bind(this));
Now let’s call it and see:


As mentioned above, this affects all methods that loop through an array and run a callback function on every iteration. That includes also .map(), .filter() and .reduce(). But what about normal loops? Let’s try:
process: function() {
var someArray = [1, 2, 3];
for(var e in someArray) {
this.logger(someArray[e]);
}
},
Works like a charm, no binding or any other magic needed. The same goes for a classic ‘for’ loop. So, unless we specifically want to use .map() or .filter() functionality, we’re safe, right?
Not quite. Say you want to do something a bit more complicated inside that loop. If you have already read our article “JavaScripture: Why loops fail – Asynchronous Code and VARs”, you could decide to play it safe with an IIFE:
process: function() {
var someArray = [1, 2, 3];
for(var e in someArray) {
(function() {
this.logger(someArray[e]);
// plus some other realy complex stuff, you know
})();
}
},
The result? Nothing:

We bind our ‘this’, and there it goes:
process: function() {
var someArray = [1, 2, 3];
for(var e in someArray) {
(function() {
this.logger(someArray[e]);
// plus some other realy comlicated stuff, you know
}.bind(this))();
}
},

That’s about it. Keep calm and bind your ‘ this’!
If you want to get deeper into JavaScripture and ServiceNow, check out our blog.