Page 1 of 2
So it is with "hoisting" a seemingly elaborate and complex piece of behavior that just seems to complicated things without any benefits.
First let's take a quick look at what the problem is that hoisting is intended to solve.
In most programming language you use functions or procedures to break the program down into small manageable chunks. One small problem that is often not mentioned is the forward reference.
Suppose you want to use a function:
but this isn't defined until later in the program's text. Should the program fail because myFunction isn't defined or should the language allow you to use functions that are defined later in the text?
Early programming languages insisted that you declare everything at the start of the program. This solved the forward reference problem because all functions and variables for that matter where defined before the main program started and hence there was no possibility of a forward reference. But it had the disadvantage of forcing the programmer to put all the functions first and the main program last. This bottom up approach doesn't fit naturally with the top down way we read a program i.e. main program first.
Later and more programmer friendly languages were less strict about where you should declare things. These allow you to put function definitions anywhere within the text of the program and use them anywhere including before they were actually defined in the text.
It does this by implementing "hoisting - a picturesque term inspired by the image of the declarations being yanked up to the top of their scope.
The rule is quite simple and it makes sense to state what it is and then explore some of its consequences.
- Hoisting moves all declarations to the start of the function that contains them.
- Hoisting moves all declarations to the start of their enclosing scope.
If the declarations are not within a function then they are moved to the start of the main program which is the scope in this case.
Of course it doesn't actually modify your program - but your program is run as if the declarations were at the start of the function.
The answer is any statement that doesn't actually get executed when the program runs. A declaration simply tells the program "compiler" or runtime something useful.
It may not have impressed itself upon you with enough force but when you write the code for a function - nothing happens.
A function definition or declaration doesn't involve actually carrying out any operations - you are simply defining the function so that it can be invoked later.
For example, if you write
this doesn't actually execute the function or do anything in your program. The text of the function is simple a definition or declaration of what the function myFunction is.
The function is executed when it is invoked using the usual parentheses notation e.g.
actually executes the function.
By the rule of hoisting then any function definition should be moved to the start of the function that contains it.
works perfectly even though myFunction is defined later in the program than it is used.
Hoisting causes the program to be treated as if it had been written as:
That is as if the function definition had been written at the start of the program.
Hoisting gathers all your function definitions and moves them to the top of their scope - the main program or the function that they are declared in.
If this seems obvious to you then you have grown accustomed, perhaps too accustomed, to the benefits of hoisting.
As will become apparent hoisting of functions doesn't work if the program if changed in away that seems insignificant - see later.
The most obvious sort of declaration is a variable declaration. For example:
declares variable a. Notice that variable a is declared and this means it exists but it doesn't have a value assigned to it - it is undefined.
For example the simple program
results in an runtime ReferenceError - myGlobal is not defined at the first line.
If you change the program to:
Then you don't get a runtime exception and alert(a) displays undefined.
That is declaring a program after it has been used still has the effect of allowing it to be used without a runtime exception.
Once again hoisting has been put into action and the declaration var myGlobal has been treated as if it was at the start of the program i.e. as if the program was:
When a variable hasn't been declared it doesn't exist and so generates an exception.
When a variable has been declared it exists and is initialized to undefined.