This code always works, even in different browsers:
function fooCheck() {
alert(internalFoo()); // We are using internalFoo() here...
return internalFoo
The function
declaration is magic and causes its identifier to be bound before anything in its code-block* is executed.
This differs from an assignment with a function
expression, which is evaluated in normal top-down order.
If you changed the example to say:
var internalFoo = function() { return true; };
it would stop working.
The function declaration is syntactically quite separate from the function expression, even though they look almost identical and can be ambiguous in some cases.
This is documented in the ECMAScript standard, section 10.1.3. Unfortunately ECMA-262 is not a very readable document even by standards-standards!
*: the containing function, block, module or script.
The body of the function "internalFoo" needs to go somewhere at parsing time, so when the code is read (a.k.a parsing) by the JS interpreter, the data structure for the function is created and the name is assigned.
Only later, then the code is run, JavaScript actually tries to find out if "internalFoo" exists and what it is and whether it can be called, etc.
Some languages have the requirement that identifiers have to be defined before use. A reason for this is that the compiler uses a single pass on the sourcecode.
But if there are multiple passes (or some checks are postponed) you can perfectly live without that requirement. In this case, the code is probably first read (and interpreted) and then the links are set.
It is called HOISTING - Invoking (calling) a function before it has been defined.
Two different types of function that I want to write about are:
Expression Functions & Declaration Functions
Expression Functions:
Function expressions can be stored in a variable so they do not need function names. They will also be named as an anonymous function (a function without a name).
To invoke (call) these functions they always need a variable name. This kind of function won't work if it is called before it has been defined which means Hoisting is not happening here. We must always define the expression function first and then invoke it.
let lastName = function (family) {
console.log("My last name is " + family);
};
let x = lastName("Lopez");
This is how you can write it in ECMAScript 6:
lastName = (family) => console.log("My last name is " + family);
x = lastName("Lopez");
Declaration Functions:
Functions declared with the following syntax are not executed immediately. They are "saved for later use" and will be executed later, when they are invoked (called upon). This type of function works if you call it BEFORE or AFTER where is has been defined. If you call a declaration function before it has been defined Hoisting works properly.
function Name(name) {
console.log("My cat's name is " + name);
}
Name("Chloe");
Hoisting example:
Name("Chloe");
function Name(name) {
console.log("My cat's name is " + name);
}
I have only used JavaScript a little. I am not sure if this will help, but it looks very similar to what you are talking about and may give some insight:
http://www.dustindiaz.com/javascript-function-declaration-ambiguity/
For the same reason the following will always put foo
in the global namespace:
if (test condition) {
var foo;
}