I suggest you read up on the documentation for this on MDN.
A function's this keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.
In most cases, the value of this is determined by how a function is called. It can't be set by assignment during execution, and it may be different each time the function is called. ES5 introduced the bind method to set the value of a function's this regardless of how it's called, and ES6 introduced arrow functions whose this is lexically scoped (it is set to the this value of the enclosing execution context).
In other words, it's complicated. It depends on context, and even which version of Javascript is running!
Context can change what is held in the this variable. For example, inside of your anonymous callback function, it isn't immediately clear whether this refers to what it did on the line before, or if it refers to action, or response, or something else. Basically, you make your callback less context dependent.
Consider this page:
<apex:page>
<button>Click Me!</button>
<script>
(function (D, w) {
"use strict";
var N = w.myNamespace = w.myNamespace || {}
N.doStuff = function () {
var self = this;
[].forEach.call(D.getElementsByTagName("button"), function (element) {
console.debug(self);
console.debug(this);
element.addEventListener("click", function (event) {
console.debug(self);
console.debug(this);
});
});
}
D.addEventListener("DOMContentLoaded", N.doStuff);
}(document, window));
</script>
</apex:page>
The onload debugs will yield:
#document
undefined
However, if you then call myNamespace.doStuff from the console, you will get:
Object { }
undefined
And if you click the button, you will get:
#document
<button>Click Me!</button>
Be wary of using this if you aren't sure what it is in a given context. Even if you alias it to self, the context in which you do so has the same issue.