Sunday, 7 July 2013

JavaScript Essential Parts : this keyword

Sunday, 7 July 2013
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.
Below I tried out all the things that we did with Object and this above, but by first creating function instead of directly writing an object. 4. When used inside constructor function When the function is used as a constructor (that is when it is called with new keyword), this inside function body points to the new object being constructed. 5. When used inside function defined on prototype chain If the method is on an object's prototype chain, this inside such method refers to the object the method was called on, as if the method was defined on the object. 6. Inside call(), apply() and bind() functions
  • 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.
  • [, 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.
7. this inside event handlers
  • 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).
So thats all what I learnt about nasty this keyword in JavaScript. I hope this helps you. Ahh! you just missed, thats this not this. ;p

Sunday, 23 June 2013

JavaScript function / protoype variables and their behavior

Sunday, 23 June 2013
I was trying out some JavaScript and suddenly surprised by awkward behavior of some function variables. Functions in JavaScript are first class citizens and are very confusing especially for OOP programmers. They always confused me too. So this time I did not took any chance and tried out some code to determine how exactly the variables defined in function behave.

I realized that we can define variables in function in many different ways:
  1. as this.variableName inside function definition
  2. as var variableName inside function definition
  3. as functionName.prototype.variableName outside function definition
  4. as functionName.variableName outside function definition
I have put the code in the below JSFiddle and explained it in the comments. Hope this helps you.
Note: The JSFiddle may not work completely on all browsers. Better view it on Chrome or Opera.