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.