Amol
Amol

Reputation: 41

Output of this javascript and the reason

function getCtr(){
  var i = 0;
  return function(){
    console.log(++i);
  }
}
var ctr = getCtr();
ctr();
ctr();

I've been using Javascript from last five years, but this question made me dumb in last interview. I tried everything to my knowledge but can't figure it out.

Can you please help me with the output and reason for it so that I can be better equipped for future interviews if I have one.

Upvotes: 4

Views: 198

Answers (8)

Luiz Sócrate
Luiz Sócrate

Reputation: 136

That function is a Javascript Module. You can have a good reading about it on Javascript: the Good Parts, which is a great book and I highly recommend. A Module uses Javascript closures to create private variables and if assigned to a var the var will retain it's vars each time it's called instead of redefining the vars.

A module works like this

function moduleName(privateVar1){
    var privateVar1;
    var privateVar2;

    return {
        exposedFunction1: function (var1) {
            // Do stuff... using private vars
            return something;
        },
        exposedFunction2: function (var1, var2) {
            // Do stuff...
            return something;
        }
    }
}

var moduleInstance = moduleName(privateVar1);
moduleInstance.exposedFunction(var1);

Upvotes: 0

nwellcome
nwellcome

Reputation: 2299

Lets break it down using terms you might know from classical inheritance based OOP languages:

// In javascript functions are first-class objects
// This function is being used like a class would be in Java
function getCtr(){
    // You can think of this as a private variable of the getCtr "class"
    var i = 0;
    // Because it is returned, this is effectively a public method of getCtr
    return function(){
        // Which increments i and then prints it.   
        console.log(++i);   
    }
}

// This makes the variable ctrl an instance of getCtr.
var ctr = getCtr();
// This calls ctr's only public method.
ctr();
ctr();

So the output would be "1, 2".

What this question is meant to do is test if you understand Javascript's prototypal inheritance, ability to have anonymous functions, and closures.

A clarified version of that could that would do the same thing would be:

var myProtoype = function() {
    var privateVariable = 0;
    var privateMethod = function () {
        privateVariable++;
        console.log(privateVariable);
    }
   return {
        publicMethod: privateMethod
   };
}

var myInstance = new myPrototype();
myInstance.publicMethod();
myInstance.publicMethod();

Upvotes: 0

Sam DeHaan
Sam DeHaan

Reputation: 10325

var ctr = getCtr();

This calls getCtr(), which initializes i to 0, and stores a reference to the function

function() {
    console.log(++i)
}

in ctr. Because that function was created in the scope of getCtr(), the variable i is still accessible in the scope of the function stored in ctr.

The first call to

ctr()

executes console.log(++i) which has a preincrement on i, so it prints out 1. The second call executes the same code, with the same preincrement, and prints out 2.

DISCLAIMER: Not a javascript developer. Forgive me if I've made an error or used some unpreferred wording.

Upvotes: 3

Simon Sarris
Simon Sarris

Reputation: 63812

So the code you posted outputs 1 2. Yet the code:

function getCtr(){
  var i = 0;
  return function(){
    console.log(++i);
  }
}
getCtr()();
getCtr()();

outputs only 1 1!

The difference is that if you save a reference to getCtr() by using the var ctr = getCtr();, you create what is called a closure.

So the difference between calling getCtr()() and ctr() is that ctr has i defined in its scope, and that scope is saved thanks to var ctr = getCtr();. Because the reference is saved, the function inside of ctr is able to always act on the same variable.

Upvotes: 1

Karol Kowalski
Karol Kowalski

Reputation: 26

When executed, function getCtr returns an inner anonymous function. This function is now referenced by variable ctr Because the anonymous function was created inside getCtr it will have access to getCtr private scope object, which contains variable 'i'. This is known as a closure.

var ctr = getCtr()

Every time the anonymous function is executed it pre-increments i, and writes in in the console.

ctr()

Upvotes: 0

Van Coding
Van Coding

Reputation: 24524

okay, getCtr is a function that returns an other function. It also contains a var called "i" which is set to 0. "i" is also available in the scope of the returned function. the preincrement of "i" before logging it to the console causes that it increases by 1 every time the returned function, which is stored in "ctr", is called.

Upvotes: 0

Joe
Joe

Reputation: 82564

Closures

The return statement in that function saves i. So when var i = 0; is only called var ctr = getCtr();. Then ctr becomes the returned function:

function () {
       console.log(++i)
   }

and the variable ctr has i in the scope of the outer function, getCtr() and the return function is in the scope of getCtr() as well.

Upvotes: 0

Mark Schultheiss
Mark Schultheiss

Reputation: 34158

run this: var m=0; var d=0;

alert(m++ +":"+ ++d);

and you get "0:1"

IF it were me asking in an interview, the difference in where the ++ is is what I would be after :) http://jsfiddle.net/MarkSchultheiss/S5nJk/

Upvotes: 0

Related Questions