Reputation: 41
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
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
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
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
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
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
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
Reputation: 82564
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
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