I believe that our OP has tasted the trade-offs of Internet learning. Accessibility to pieces of information, but no guide to it. Unfortunately, we don't know how much you know and we assume lots of things, and those are that you know few things that are a prior knowledge that ultimately leads to an understanding of what dreaded hoisting
is. This is typical how magnets work, and by that, I will provide some keywords that should serve as guidance to your understanding of JavaScript.
Creation Stage
+ Activation aka Code execution Stage
= Execution context
Ok but what are each of those?
Scope Chain
+ Creating arguments, functions, variables
+ value of 'this' keyword
= Creation Stage
and
Assigning values and references to functions, then execute the code
= Activation aka Code execution Stage
code 1 Start executing line by line following the algorithm above.
Stage 1: Creation stage
globalExeContext = {
//no scope
objForVariables = {
//no arguments because its no function
// function declarations
b: `points to function`,
// variable declarations
a: `undefined`
},
this: //not important for this example
}
And the creation stage is done. We went line by line with the defined instructions above. Now we are in the execution stage where assigning =
and executing ()
happends. Once more we start from the line 1
Stage 2: Execution stage
globalExeContext = {
//no scope
objForVariables = {
//no arguments because its no function
// function declarations
b: `points to function`,
// variable declarations
a: 1 // because we did the `=` on line 1
},
this: //not important for this example
}
and then on line 8, we found the function execution which means that create new execution context on top of global execution context, and that means we follow the algorithm above once more for that function.
Stage 1: Creation stage
bExeContext = {
// This is the scope object, and in this object now is placed the global exe context we have worked on before
scope: {globalExeContext}
objForVariables = {
//the is arguments object for this one but its empty, because we have no arguments for this function
args:{},
// function declarations are none here
// variable declarations are none here
},
this: //not important for this example
}
Now, we have entered the execution stage where we do ()
and =
. On line 1 it is told that a = 10
which means we need to find a
to assign the value to it. But we don't have a
in bExeContext
object? What now? Now we go into scope
and try finding it in there. Sure enough, there is a
in our global space and now we assigning 10 to it. We have overwritten it. It will never be the same, and i will bring back the globalExeContext to show you that.
Stage 2: Execution stage
globalExeContext = {
//no scope
objForVariables = {
//no arguments because its no function
// function declarations
b: `points to function`,
// variable declarations
a: 10 // look what you have done
},
this: //not important for this example
}
now that this is resolved, we go back executing the next line in our b
function and that is console.log(a);
. We need to resolve what a
is and going all again, searching in b
gives us nothing, but we have it in globalExeStack. You remember, it is 10
. So we log 10
. We have reached the end of the function and it is popped off the stack. It is no more.
Now we resume executing the last line of our global code: console.log(a);
and easy enough, there is a
in globalExeStack. It is 10
.
code 2 Stage 1: Creation stage.
globalExeContext = {
//no scope
objForVariables = {
//no arguments because its no function
// function declarations
b: `points to function`,
// variable declarations
a: `undefined`
},
this: //not important for this example
}
Stage 2: Execution stage =
and ()
Line one is the same
globalExeContext = {
//no scope
objForVariables = {
//no arguments because its no function
// function declarations
b: `points to function`,
// variable declarations
a: 1
},
this: //not important for this example
}
and line 8 tells to execute b
function.
Stage 1: Creation stage
bExeContext = {
scope: {globalExeContext}
objForVariables = {
//the is arguments object for this one but its empty, because we have no arguments for this function
args:{},
// function declarations
a: `points to function`
// variable declarations are none here
},
this: //not important for this example
}
Stage 2: Execution stage
line 1 tells to find a
and assign 10
to it. We are lucky this time because a
can be found in our bExeContext.
bExeContext = {
scope: {globalExeContext}
objForVariables = {
//the is arguments object for this one but its empty, because we have no arguments for this function
args:{},
// function declarations
a: 10 // no longer points to `points to function`
// variable declarations are none here
},
this: //not important for this example
}
and that means that we did not have to go to global space to find a
. Line 2 of executing b
function tells console.log(a);
. We need to resolve what a
is and sure enough
bExeContext = {
// blablbalblablbalblablblal
// blablbalblablbalblablblalb
a: 10 // no longer points to `points to function`
// blablbalblablbalblablblalb
},
// blablbalblablbalblablblalb
}
we did found it on bExeContext. We log 10
. We finished executing b
function and we pop it out of execution stack. It is no more.
We resume evaluating global code now. We finished the b();
which was on the 9th line, now we are on line 10. console.log(a);
and to resolve a
we have to find it first. To refresh how our globalExeContext looks, here is the last picture:
globalExeContext = {
//no scope
objForVariables = {
//no arguments because its no function
// function declarations
b: `points to function`,
// variable declarations
a: 1
},
this: //not important for this example
}
Sure enough, a
is 1
. We log 1
. We are done.
You see, hoisting
is achieved as soon as you run JS code. It is the process of laying down the bits of code, sorting it out if you will. More precisely it was 1.arguments 2.function declarations 3.variable declarations. Hoisting happends when your code is just few line or one line, or without any functions at all because as soon you try and play the part of interpreter and laying out the code, you did the hoisting.