IMHO, hoisting
is a really bad concept that just happens to be useful. It leads to minunderstandings such as yours. The real way the interpreter works is something like my answer to this related question: JavaScript function declaration and evaluation order
For your specific example, you mention:
when const do not get hoisted
This is not really true. Of course, hoisting does not really exist in the language, it is just a concept programmers created to explain how the language behaves. Let's see how your code is interpreted when we split the parsing into two phases: compilation and execution:
function fun() {
function log() {console.log(callme) };
console.dir(log);
setTimeout( log, 10000);
const callme = "hi iam"
}
fun()
Compilation phase
- OK, we have a function definition
fun
, let's parse it's body
- OK, we have a function definition
log
, let's parse it's body
- OK, we're logging a variable
callme
. Note the variable we are using
- We want to call
log
after 10 seconds, Note the function setTimeout is using
- We define a constant
callme
Execution phase
- OK, we are calling
fun()
- We are declaring a function log(), create an instance of it
- We output the definition of
log
- we are calling
setTimeout()
, find a variable/function called log
- found it, add log
to event queue
- Set the value of
callme
to "hi iam" (note that values cannot be set in compilation phase because it may involve executing code for example if we do const x = (1).toString()
, const just means we cannot set the value outside of initialisation)
- End of function call, we detect that
callme
is used in a closure, attach it
- 10 seconds pass by, OK event loop detects timeout, call
log()
- We need to log
callme
- found it in a closure, log it.
This is how callme
gets pulled into foo
's closure. If you insist on using the hoisting
terminology you can say that if there is a closure then const gets hoisted.
But you don't really need to know all the corner-cases of when hoisting happens and when it does not if you have as your mental model this two-phase interpretation. I strongly suggest reading the answer linked above to get a better understanding of how it works.