Zach Smith Zach Smith - 1 year ago 51
Javascript Question

Javascript: why do callback functions with global execution context have access to scoped variables?

In the following code:

function test() {
var x = 5 // scoped to test function
console.log(this); // global object
console.log(this); // global object

function logCb (cb) {
console.log(this); // global object
cb() // This still seems to execute within the test function scope? why...


x is scoped to test, and this is where the callback function is defined. I would have expected line
to throw an error, as the logCb() function does not have access to the x variable.

However this is not the case. Why? It seems like references within the callback are created during assignment, and NOT during execution - which I guess makes sense if you consider hoisting - i.e. during compilation, is the callback function is hoisted to the top of 'test' and then assignment happens within test's scope?

I have read that execution is not the same as scope. In this article:, this sentence
scope pertains to the variable access of a function when it is invoked and is unique to each invocation
seems to imply that the callback is invoked from within the test function.

Because it seems to me that no matter where the callback function is invoked it would still be scoped to test.

I think my question is:

How is the callback function handled in terms of definition and then invocation when thinking about scope and execution context?

Answer Source

How is the callback function handled in terms of definition and then invocation when thinking about scope and execution context?

A function scope is based on where it is physically present in the lexical environment

Explanation: The callback is lexically present in the function test(), so it will always try to find the value of this either within itself(if present) otherwise it will see its value in the outer environment (which is function test in this case)

The test function and LogCb function will follow the same practice. In this case the outer environment will be global

how does the engine keep track of scope separately to execution context?

Lexical Environment: Where something sits physically in the code you write.

Execution Context: A wrapper to help manage the code that is running.

Now in your code there are lot of lexical environments. Which one is currently running is managed via execution contexts. It can contain things beyond what you have written in your code.

Whenever execution context is created we have three things that are available to us:

  1. Global object (window) :Any variable or function in the global scope is linked to window object
  2. 'this'
  3. Outer environment

So depending on which execution context is currently running, these things will vary as per where it is physically or lexically present in code. For example the outer environment for cb is the function test()