If I understand correctly, in the creation phase, the variables and functions are 'set', meaning they are given spots in memory.
I would not use the term set for this--it usually is used to refer to a variable being set to (assigned) a particular value. I also would not use the term "spot" or "memory"--we don't need to worry about these internals. It's clearer just to say declared.
I also don't really like the use of the term "creation phase", which is both non-standard and confusing--what is being created, exactly? I would prefer the term "compilation".
The variables are all given the placeholder value of undefined.
To be precise, I would not say they "have the value of undefined", but rather "have no value", or "are not defined". undefined
is not a value held by a variable which has not been assigned to yet; rather it's a state, which causes the variable to evaluate to the undefined
value when accessed.
Alternative 1: In the creation phase, all variables are set before functions.
Yes, although again it's going to be confusing to use the word "set". Say, "all variables are declared before functions". This is the process of hoisting.
Alternative 2: the functions and variables are set in the lexical order they are in (in this case, b is created before a), and when b is created, the 'a' reference somehow means that the function is listening for any possible creation of an 'a' memory location, and when later the 'a' location is actually created, the reference refers to that spot.
No. The function does not "listen" to anything. It just executes when you tell it to.
Is this important?
Not really. It falls into the category of arcana. So we clog up our brains with rules like, variables hoist this way, function declarations hoist some other way, let
has yet some other hoisting behavior. In practice, almost all style guides will call for you to declare variables at the top of the function, and linters will warn you if you don't (or can be configured to do so). This immediately eliminates all variable hoisting issues.
Some people like to put internal functions at the bottom of their function, and that works fine since, if it's a function declaration (ie function foo() { }
) the whole thing (including the definition) is hoisted. If it's a function expression being assigned to a variable (ie var foo = function() { }
), then it's a variable, and we already decided to put those at the top of our function--see paragraph above.
In general, if your program depends on hoisting behavior, it's written badly. If you need to understand hoisting behavior to understand how the program works, it's written badly.
To summarize, all you really need to learn is one rule: put variable declarations (and their initializations) at the top of your function. Then you don't have to worry about hoisting at all.
(There are some exceptions, such as declaring a variable inside a for
statement, as in for (var i...)
, which is fine, assuming i
is not being used for anything other than the index of the loop.)
For some reason, people learning JS seem sometimes to focus on these oddities--such as "why does " " == false
or something. I would suggest instead focusing on the how to think about your problems, and break them down, and writing nice clean code that just works, and that you and other people can maintain without worrying about the arcana. I've been writing JS for many years, and cannot remember the last time I encountered a problem related to hoisting.
var
statements, the declaration of the variable is hoisted, but the assignment part is not. So your alternative 2 is wrong. And about the alternative 1, I think all variables and functions are assigned memory at the same time conceptually. – Sherrilsherrill