The this keyword behaves differently in JavaScript compared to other language.
In Object Oriented languages, the this keyword refers to the current instance of the class.
In JavaScript the value of this is determined mostly by the invocation context of function (context.function()) and where it is called.
1. When used in global context
When you use this in global context, it is bound to global object (window in browser)
When you use this inside a function defined in the global context, this is still bound to global object since the function is actually made a method of global context.
Above f1 is made a method of global object. Thus we can also call it on window object as follows:
2. When used inside object method
When you use this keyword inside an object method, this is bound to the "immediate" enclosing object.
Above I have put the word immediate in double quotes. It is to make the point that if you nest the object inside another object, then this is bound to the immediate parent.
Even if you add function explicitly to the object as a method, it still follows above rules, that is this still points to the immediate parent object.
3. When invoking context-less function
When you use this inside function that is invoked without any context (i.e. not on any object), it is bound to the global object (window in browser)(even if the function is defined inside the object) .
Trying it all with functions
We can try above points with functions too. However there are some differences.
- Above we added members to objects using object literal notation. We can add members to functions by using this. to specify them.
- Object literal notation creates an instance of object which we can use immediately. With function we may need to first create its instance using new operator.
- Also in an object literal approach, we can explicitly add members to already defined object using dot operator. This gets added to the specific instance only. However I have added variable to the function prototype so that it gets reflected in all instances of the function.
- All these methods are defined on Function.prototype.
- These methods allows to write a function once and invoke it in different context. In other words, they allows to specify the value of this which will be used while the function is being executed. They also take any parameters to passed to the original function when it is invoked.
- fun.apply(obj1 [, argsArray])
Sets obj1 as the value of this inside fun() and calls fun() passing elements of argsArray as its arguments. - fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
Sets obj1 as the value of this inside fun() and calls fun() passing arg1, arg2, arg3, ... as its arguments. - fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
Returns the reference to the function fun with this inside fun bound to obj1 and parameters of fun bound to the parameters specified arg1, arg2, arg3,.... - By now the difference between apply, call and bind must have become apparent. apply allows to specify the arguments to function as array-like object i.e. an object with a numeric length property and corresponding non-negative integer properties. Whereas call allows to specify the arguments to the function directly. Both apply and call immediately invokes the function in the specified context and with the specified arguments. On the other hand, bind simply returns the function bound to the specified this value and the arguments. We can capture the reference to this returned function by assigning it to a variable and later we can call it any time.
- When you assign function directly to event handlers of an element, use of this directly inside event handling function refers to the corresponding element. Such direct function assignment can be done using addeventListener method or through the traditional event registration methods like onclick.
- Similarly, when you use this directly inside the event property (like <button onclick="...this..." >) of the element, it refers to the element.
- However use of this indirectly through the other function called inside the event handling function or event property resolves to the global object window.
- The same above behavior is achieved when we attach the function to the event handler using Microsoft's Event Registration model method attachEvent. Instead of assigning the function to the event handler (and the thus making the function method of the element), it calls the function on the event (effectively calling it in global context).