1

Functions returning from a method keep a copy of their parent execution context, and this is called closure. But what if the function is inside another function which is inside another function like this:

const a = function() {
    const aa = 'aa';
    return function() {
        const bb = 'bb';
        return function() {
            return aa;
        }
    }
}

Now, if I call it like:

a()()();

It'll return "aa" because the nexted-most method seems to have access to its grandparent context. So, do all inner methods keep the execution contexts of all their ancestors in which they're nested, when these inner methods are returned?

Daud
  • 7,429
  • 18
  • 68
  • 115

2 Answers2

3

So, do all inner methods keep the execution contexts of all their ancestors in which they're nested, when these inner methods are returned?

For almost all practical purposes: Yes.

JS engines do optimise though, so in practise only data that needs to be kept around is kept rather than the whole lexical environment.

For example, given:

const a = () => {
    const foo = 1;
    const bar = 2;
    const b = () => {
        console.log(foo);
        debugger;
    }
}

a()();

Most JS engines will make foo available to b but, because b doesn't use bar, they will discard bar and it won't be available to the debugger.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Is a closure created every time a function is called, even if its not being returned from from an outer function? – Daud Sep 21 '21 at 16:49
  • 1
    @Daud closure is formed when the function is created; not when it is called. Every time you create a function, it forms a closure over the environment in which it is created. – Yousaf Sep 22 '21 at 05:11
2

Closure is just a reference to an environment in which a function is defined.

In the code example (I have given each function a name to make it easy to explain):

const a = function() {
    const aa = 'aa';
    return function b() {
        const bb = 'bb';
        return function c() {
            return aa;
        }
    }
}

function c will have a reference to the local scope of function b. Similarly, function b will have a reference to the local scope of function a.

This chain of references is what's known as a scope chain and Javascript will traverse this chain until it finds the identifier aa.

Reference to the environment in which a function is defined is saved in an internal slot which the Ecmascript specification calls the [[Environment]] slot of the function object.

Yousaf
  • 27,861
  • 6
  • 44
  • 69