javascriptscopeexecutioncontext

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
    logCb(function(){
        console.log(this); // global object
        console.log(x);
    })
}

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

test()

x is scoped to test, and this is where the callback function is defined. I would have expected line cb() 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: http://ryanmorr.com/understanding-scope-and-context-in-javascript/, 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?


Solution

  • 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()