Update: Re your edit, see below under the divider.
The code as you've given it won't work. We can reorder it a bit to make it work, though:
var func = function(x) {
return x * x;
};
console.log(func(10)); // 100
var func = function(x) {
return x + x;
};
console.log(func(10)); // 20
Here's what happens with the above:
Before any step-by-step execution of the code, the browser scans the code for var
declarations. It finds the first var func
and so it creates a variable in the current context with that name. Then it finds the second var
, but as the name is the same, it does nothing with the second one. At this point, func
has the value undefined
. (This bit where it does var
in advance is called "var hoisting.")
Now, step-by-step execution of the code begins.
The engine assigns a function to the func
variable.
The engine calls func
, passing in 10
. func
returns 10 * 10
(100
); the engine passes that value into console.log
, which writes it out.
The engine assigns a new function to the func
variable.
The engine calls func
, passing in 10
. func
returns 10 + 10
(200
); the engine passes that value into console.log
, which writes it out.
So what's wrong with the code as you've shown it? Here's how the engine runs the code as it is in the question:
Before any step-by-step execution of the code, the browser scans the code for var
declarations and creates the variables as in #1 above.
Now, step-by-step execution of the code begins.
The engine tries to call func
, but the value in func
is currently undefined
, and so it fails with an error.
Re your edit: The code you've posted from Eloquent JavaScript is very different:
console.log("The future says:", future());
function future() {
return "We STILL have no flying cars.";
}
That uses a function declaration, whereas your earlier code used function expressions. This question and its answers go into detail, but declarations and expressions, even though they look really similar, behave very differently from one another. Here's the order of things with the above:
The JavaScript engine scans through the code looking for function declarations and processes them in source-code order. So it sees function future() { ... }
and creates the function, associating it with the in-scope identifer future
. This is called "function declaration hoisting" and it's a bit like var
hoisting above, because it happens before any step-by-step code is done.
Then the step-by-step execution begins.
The engine calls the future
function, gets its return value, and then calls console.log
using that return value.