September 23, 2012

Understanding the output of this javascript code

Question by iamrohitbanga

Having programmed in C/C++, Java I am finding difficulty understanding the output of the following program.

http://jsfiddle.net/iamrohitbanga/nubgw/

var foo = function() {}
foo.prototype.out = function() {
    console.log(this.num);
}
var bar = function() {};

var f = new foo();
f.num = 1;
var b = new bar();
b.num = 2;

console.log(this);           // 1
f.out();                     // 2
foo.prototype.out.call(b);   // 3
foo.prototype.out.call(bar); // 4

I see the following output

Window
1
2
undefined

I have been coding in javascript for a while now and can understanding some of the concepts but not everything is clear to me.

I have a rough understanding.
I feel in the global space this points to the window and hence the first line of output is clear.
For the second line I think since the function out is being invoked on f the value of this in out is f.
For the third one my feeling is that by calling the function with input as b, the value of -this is set to b.
For the fourth one bar is a global object which has no member named ‘num’ in its dictionary.

Is my understanding correct?
Can someone explain the role of ‘this’ and ‘prototype’ in the context of this program? I find the syntax of prototype slightly obscure.
Also in chrome when I press F12 while in gmail window and paste the program in there. The third line of output is undefined and not 2. But in jsfiddle it is two. which seems somewhat creepy. Why is it different?

Answer by Starx

this represents the scope from where the code is executing. In your case, it is the global scope window.

Prototypes in JavaScript are simply an object with properties and methods. You can add members to it and also inherit from it. You can read this article for further information.

Lets break down your code are see this one by one.

  1. f.out();

    This refers too the following object

    var f = new foo();
    f.num = 1; //Here you define a property `num` as 1
    

    Then when you call f.out() the prototyped function will simple log the num

  2. foo.prototype.out.call(b);

    Here you directly access the function and pass an object to the function. Thus when the method is executed, this represents the object that is pass instead, so ends up logging its value.

  3. foo.prototype.out.call(bar);

    On this part, the object bar is an empty object var bar = function() {};, thus the function cannot read its num property, so it outputs as undefined

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!