However in JS its: scope isn't assigned when the function is defined and compiled rather it's assigned at runtime i.e. when the function is called
I think you are confusing yourself with this description of scope in JS. A more accurate description of scope in JS is given by this article (emphasis added):
Because functions are also defined at this time (lexing phase), we can say that lexical scope is based on where variables and blocks of scope exist at author time, and thus are locked down at the end of the lexing phase. Scope is not defined at runtime, rather it can be accessed at runtime.
So, in your example:
function f() {
console.log(x);
}
const x = 10;
f(); // 10
What is happening is that the scope chain of function f
consists of:
- its local scope
- the outer, global scope
and this "scope chain" is defined at author time (i.e. lexical scope).
At author time, the constant x
is defined within the global scope, and when f
is called, x
is available within the global scope. That x
is not defined when the function f
is declared (but NOT called) is irrelevant for this discussion.
Also, you are incorrect when you mention "hoisting" regarding your code example: variables declared with const
are NOT hoisted.
If we alter your example, we will get a Reference Error, since the constant x
has not been initialized in the global scope (i.e. on author time), when the function f
is called (and function f
looks through its scope chain, which has been defined on author time):
function f() {
console.log(x);
}
f(); // 10
const x = 10;