One of the most confusing topics in JavaScript is the ‘this’ keyword. In high-level programming languages, such as Java, ‘this’ is referring to the current object instantiated by the class. In JavaScript ‘this’ normally refers to the object which owns the current method or function, but this depends on how the function is executed.
Every JS runtime has a global object; in a browser that global object is the window. The window object stores the information about the document, location, history and many other useful properties and methods. Consider the following example where I will add a property to the global object.
window.globalProperty = "I am the global object"; alert(window.globalProperty); //I am the global object alert(this.globalProperty); // I am the global object alert(window === this); //true
I’ve attached my property globalProperty to the window and you can see by calling it using the window object or with ‘this’ that ‘this’ refers to the window object.
‘this’ remains in the global scope even if you’re calling it using a function.
window.globalProperty = "I am the global object"; function testScope() { alert(this.globalProperty); //I am the global object alert(window === this); //true } testScope();
Using objects
However, for method functions, that is functions that are referenced using object properties the scope can change.
NewObject = { method: function(val) { this.val = val; } } NewObject.method("hello"); alert(NewObject.val);//hello
The value of ‘this’ is bound to NewObject at invocation. In simpler terms, since NewObject is the receiver of the call to the method function call, the current scope is NewObject not the window.
Things get more unintuitive when using ‘this´ inside a nested function.
NewObject = { method: function(val) { this.val = val; var nested = function() { alert("The value was set to " + this.val); // The value was set to undefined } nested(); } } NewObject.method("hello");
The value of ‘this´ refers to the global object and is not bound to NewObject like its parent. This is because nested is invoked on a method and does not have a receiver like the example above (NewObject.method(“hello”);). This is true no matter how the function is scoped. That is why you will often see code like this:
NewObject = { method: function(val) { var self = this; this.val = val; var nested = function() { alert("The value was set to " + self.val); // The value was set to hello } nested(); } } NewObject.method("hello");
By assigning ‘this’ to a variable you can get around the default behavior.
Using the new operator
The new operator can override the default behavior of how ‘this’ is usually bound. When you invoke a function with new, you’re invoking it as a constructor function and creating a new object.
function testScope(val) { this.val = val; } NewObject = new testScope("hello"); alert(NewObject.val); //hello
Using Call and Apply
The functions call and apply allow you to pass an argument for the object you wish ‘this’ to be bound to.
function testScope(val) { this.val = val; } NewObject = {} testScope.call(NewObject, "hello"); alert(NewObject.val); //hello
The only difference between call and apply is that apply allows you to invoke a function with arguments as an array, call requires you to list the parameters explicitly.
Do you have any questions or comments? Please leave us a message below or tweet us @Pixafy!