Reputation: 193352
I'm coming from C#/PHP and trying to get my head around Javascript's idea that functions are variables/objects and have quasi constructors, etc.
Can anyone explain why the following code functions as it does, namely:
test
?test
?code:
var setup = function () {
console.log(1);
return function() {
console.log(2);
};
};
var test = setup(); // 1
test(); // 2
test(); // 2
test(); // 2
Thanks @thejh @Justin so the function is returning a completely different function that has nothing to do with the first (I was thinking of the second function as a kind of constructor of the first), if I comment it out, it's clearer:
$(document).ready(function() {
var setup = function () {
console.log(1);
// return function() {
// console.log(2);
// };
};
var test = setup(); // 1
test(); // "test is not a function"
test(); // "test is not a function"
test(); // "test is not a function"
});
Upvotes: 2
Views: 344
Reputation: 44346
Imagine instead of
var setup = function () {
console.log(1);
return function() {
console.log(2);
}
}
this equivalent OOP syntax
var setup = new Function("\
console.log(1);\
return new Function(\"\
console.log(2);\
\");\
");
var test = setup(); // 1
test(); // 2
test(); // 2
test(); // 2
I think things should be more familiar to you now.
Upvotes: 1
Reputation: 3384
Hello when you do setup()
you execute this two lines :
console.log(1);
function() { console.log(2); }
when you do test()
you actually call the function you've created and so you log "2"
JS is a functional language, you have to see functions like first citizen object.
Upvotes: 1
Reputation: 45578
Calling setup()
prints 1
and returns a reference to that anonymous function. Calling that prints 2
.
Upvotes: 1
Reputation: 32355
In your first assignment of test to setup(), you're executing the whole function, so console.log(1)
runs, then returns a new function.
Now, you're assigning the return value of that first function to be the next function that runs console.log(2)
, so now test references that returned function.
Your subsequent calls just run that function which runs console.log(2)
Upvotes: 1
Reputation: 245449
You're only calling setup()
the first time. Once it is called, the new function it returns is assigned to test
. From there on, you're calling that new function:
// calls setup which logs 1 and returns a new function.
// setup also returns a new function and assigns that new function to test.
var test = setup();
// test now is the equivalent of var test = function(){ console.log(2); };
// call the new function that setup returned which logs 2
test();
// and again
test();
// and again
test();
Upvotes: 5
Reputation: 630549
Because you're returning a different function from what gets called when creating it (the one in the return
, one you're not calling on the first line)...that's what gets executed on the other calls. For example this would give you 1
then 2
:
var test = setup()(); // 1, 2
Upvotes: 5