Hy guys. I dont understand something regarding the hoisting and it can be it is my bad, but I didnt find any answer, neather here nor on google, thatswhy I ask, thanks for reading.
So I dont understand, As the javascript engine gets my code below and starts to scan through, will be the whole code with all functions and nested functions scanned threw, until to the very last scope? And the creation phase of all function will take place for the first scan (or with others words will the full code be scanned just once and prepared everything for each functions)?
/* Global execution context*/
function myFirst(){ /*Scanner meets this code and hoists it*/
var A = "12"
return function myFirstB(){ /*As the scanner arrived here and
scanns threw this function during the parents hoisting period ( or just before the global contexts execution phase) will it be hoisted as well, that it gets [[Scopes]] property? So that when I call it in the last line as a closure, it can remember on, that variable "A" is in its outer-environment?*/
console.log(A)
} //myFirstB()
} // myFirst()
function mySecond(){
alert("one")
}
var myClosure = myFirst();
myClosure(); /*before beeing called does this function have already [[Scopes]] property/scope-chain?*/
Or the hoisting happens nest-level by nest-level? So I mean at first those functions will be hoisted which are defined in the global context? and then as one of those functions gets invoked and its execution-contexts execution phase starts, will be its nested functions hoisted?
I am investigating this, because I dont really udnerstand, how a nested function remembers on, in which lexical environment/function has it been defined, if it wasnt already at least hoisted, that it has a [[Scopes]] property, which preserves its scope chain
The probelm is all the articles I saw until now and even the ecmascript 6 documentation says only, that the hoisting happens, if the scanner meets a function definitiona and then the scope property will be created with the scope chain and variable object the arguments object and the "this" keyword, but I didnt find any material which would talk about, if the nested functions (which are preserved in the variable object, coupled there with a reference to their function body in the memory) will be at least hoisted as well (at the same time, their parent function is hoisted) and soo they get a scope chain to remember on their outer environment, if they are called outside from there outer-environment
Thanks a lot guys for reading threw my tonns of words, if you can answer it or if you have an article which talks about this aspect as well of hoisting, I would really appriciate
I think you are confused because you tangled too many things. You will need to distinguish three things:
The parser does indeed scan through the whole code. If there was a syntax error anywhere, none of the code would be run. It does parse the whole code into a (nested) structure that is suitable for execution later. This might be an abstract syntax tree or executable byte code, or anything in between - that's an implementation detail.
Before a chunk of code is run, like in the global scope or a block scope or a function scope, the context for that execution has to be created and initialised first. It does get a parent scope reference (e.g. the scope surrounding a block or the scope a closure was defined in), a this
value, and a new variable environment in which the variables of this scope are created. Here is where all the variable names declared in the scope (e.g. function parameters, var
and function
and let
and const
and class
declarations etc) are used to instantiate a new variable.
When the code chunk is executed statement for statement and expression for expression, the variables already exist. This is when the values are created and assigned to the variables. When a function is defined, it does become a closure by referencing the current scope.
The term "hoisting" is giving the wrong impression. No source code is moved around. How an implementation achieves the specified behaviour is not restricted. It might be that the parser creates byte code that has the creation of the variables at the top of each scope. It might be that in the initialisation phase of a scope it scans the AST for declarations every time. It most likely is a mix of those in the form of a just-in-time compiler, which creates the byte code only when the function is called for the first time.
Regarding your question about nested functions, remember that the inner function is re-created every time the outer function is called. It is only "hoisted" to the top of its scope, not outside of the outer function, and will be redefined on every run of the code.