
In JavaScript, this
keyword always depends on how given function is invoked. There are four patterns to invocate a JavaScript function. Understanding those patterns is important knowledge to understand how JavaScript this
keyword works.
Learn JavaScript this keyword by reading this article.
JavaScript this keyword
In a JavaScript function, this
keyword refer to the object that the function is a method of. Every function invocation pattern differ in how JavaScript this
variable is initialized.
Method Invocation
A function is called a method when it is stored as a property of an object. When a method is invoked, this
keyword is bound to the object where the function is defined.
A function is defined as a method when it’s invoked through an object (contains a dot or [] expression, ie. someObject.myFunc()
or someObject["myFunc"]()
).
var someObject = { message: "Hello!", greetMe: function() { // "this" bounds to someObject and allows to access it's properties alert(this.message); } } someObject.greetMe(); // = Hello!
Function Invocation
Invocation as a function takes place when a function is not a property of an object.
When a function is invoked this way, this
keyword is bound to the global object. In web browsers this global object will be window
.
Invocation as a function can take place also when a function is inside of some object:
window.message = "I am the window object!"; var someObject = { message: "I am the someObject!", invokeMethod: function() { alert(this.message); }, invokeFunction: function() { var func = function() { alert(this.message); } func(); } } someObject.invokeMethod(); // = "I am the someObject!" someObject.invokeFunction(); // = "I am the window object!"
The way of this
behavior during invocation as a function is a terrible mistake of JavaScript design. Thankfully, there exist a very handy workaround that allows to access properties of the object in which the function is defined:
window.message = "I am the window object!"; var someObject = { message: "I am the someObject!", invokeMethod: function() { alert(this.message); }, invokeFunction: function() { var that = this; var func = function() { alert(that.message); // notice "that" } func(); } } someObject.invokeMethod(); // = "I am the someObject!" someObject.invokeFunction(); // = "I am the someObject!
Constructor Invocation
When a function is invoked by using the new
prefix, a new object is created (and returned) using prototype of this function (read more about prototypes in this post).
During Constructor Invocation of a function this
keyword refers to the newly created object.
window.message = "I am window.message" // Constructor invocation example var Messenger = function(message) { this.message = message; } var myObject = new Messenger("I am myObject.message"); alert(window.message); // = I am window.message alert(myObject.message); // = I am myObject.message // In Constructor Invocation "this" refers to // the object being created, thus this.message in Messenger // set "message" property in "myObject", not "window" // Function invocation example Messenger("I am set by Invocation as Function"); alert(window.message); // = I am set by Invocation as Function // In Function Invocation "this" refers to // the global object, thus this.message in Messenger // set "message" property in the global object "window"
Invocation of a constructor function in any other way than with usage of new prefix may lead to terrible consequences. An example can be unintentional overriding of the global object, as shown in the example above.
Due to this problem there is a very important convention that marks which functions should be always invoked as a constructor. Every function that should be invoked as a constructor should begin it’s name with a capitalized letter.
Notice that the name of constructor function Messenger
starts with a capitalized letter specially to mark that it should be always invoked as a constructor. Please keep in mind this convention to prevent problems in your and others code.
.apply() Invocation
The apply()
method is present in every JavaScript function. It allows to invoke a function with this
bounded to an object of your choice.
apply()
method accepts two arguments. The first is a replacement for this
object. The second is an array of arguments that is passed to that function.
The syntax of apply()
is following:
Usage example:
var someObject = { message: "I am someObject", getMessage: function(p1, p2) { alert(this.message + "; Params: "+p1+","+p2); } } var otherObject = { message: "I am otherObject" } someObject.getMessage("x", "y"); // = I am someObject; Params: x,y someObject.getMessage.apply(otherObject, ["x", "y"]); // = I am otherObject; Params: x,y
You got it explained so easily! I had problem always with `this` keyword. Thanks!