'This' in Javascript
The 'this' can change based on the execution context. Depending on how the function is invoked. Determined by who is invoking the function and how the function is invoked.
The 'this' keyword in constrast to how scoping works (All determined at statically at compiled time), the 'this' keyword is based on how you invoke a method.
Note:
If we don't supply a context to a function call, it gets the global context. (In not strict node)
'this' only changes value where a particular function or situation contextually supplies it with one.
'this' (in the absence of new, bind, call or apply magic) refers to the object in which the function was called.
When 'this' is called in a function, will link to the Global Object,
when the function is a method on an object, the 'this' points to the object.
When we have internal functions within a object, when its execution context is created,
the 'this' refers to the Global Object, so we need to do the self = this or uses bind.
More info: http://stackoverflow.com/questions/11273428/this-inside-nested-function
What is on the left-hand side of a function invocation, determines what the 'this' keyword points to:
eg: person.printName();
Example 1:
function example () {
console.log(this); //Log the window object
}
console.log(this);// Log the window object
example();
Output:
Global object
In function, the 'this' keyword won't always point to the object it was defined on unlike statically scoped variable, that are bound at compiled time.
The 'this' keyword is bound at runtime and it can change.
Example 2:
var person = {
name: "Nelson",
printThis: function(){
console.log(this); //this reference that object -> this.name will get 'nelson'
}
};
person.printThis();
Output:
[object Object] {
name: "Nelson",
printThis: function (){
window.runnerWindow.proxyConsole.log(this);
}
}
Example 3:
var button = document.getElementById("button-1");
button.addEventListener("click", function(){
console.log(this);
this.innerText = "I was clicked"
});
Output:
-> Was the element that was clicked
//The 'this' is not part of an object, it is just a callback function:
-> <button id = "button-1"> Press Me </button>
//This behaviour is consistent, it follows some rules.
Example 4:
var person = {};
person.firstName = "Nelson";
person.printName = function() {
console.log(this.firstName)
};
What if we wanted the function 'printName' to be invoked when we clicked a button?
You might have done something like:
button.addEventListener("click", function(person.printName)); //Passing a function thats attached to an object to a click handler.
Output:
We get 'undefined', why:
- The method is indeed getting invoke
- The 'this' variable refers to the button
- When we pass in person.printName as a callback to the callback of the click handler, when it gets invoke, the 'this' is not the object that had the method on it, the 'this' is the button. The button has no property called 'firstName'.
Example 5:
var doThing = person.printName;
doThing(); -> 'undefined'
person.printName(); -> 'nelson'
Example 6:
var person2 = {
firstName: "Foo"
}
person2.printName = person.printName;
person2.printName(); -> 'Foo'