1

Hi I'm reading the book series "You Don't Know JS". I'm on my second pass where I try to get a deeper understanding of the content. While going over the chapter on scopes and closures. The following scenario occurred to me:

Consider this example

function test1(){
  var a = 2;
  return function(){console.log(a)};
}

var b = test1();
b();   // 2
var c = test1();
c();   // 2

The returned function from "test()" maintains a closure over the scope of "test". So each time we call this returned function we get the value of the variable "a" which in this case is "2". Now consider this example:

function test2() {
  var a = Date.now();
  return function() {console.log(a)}
}

var b = test2();
b();  // 1551867093995
var c = test2();
c();  // 1551867109249

Each time we execute "test()" the variable "a" gets assigned the time the function "test()" was invoked and returns a function that maintains a closure over the scope of "test()".

We call "test()" on two separate instances assigning the returned function to the variables "b" and "c".

Notice when we call "b()" and "c()" we get 2 different values even though each invocation references the same variable in the same scope (var a).

It seems that each time we invoke a function (for example "test2()") the engine creates a unique instance of the declared functions scope for each invocation of that function, and whatever closure exists, closes on a unique instance of the function scope. It's as if the each function declaration creates a "Scope class" that describes its own scope and each time the function is invoked an instance of that "scope class" is created. Is this really the case? Could someone explain this behavior or point me to resource that give a deeper explanation of JavaScript scopes?

Thank you

  • Possible duplicate of [How do JavaScript closures work?](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – VLAZ Mar 06 '19 at 11:19
  • "*each time we invoke a function the engine creates a unique instance of the declared functions scope for each invocation of that function*" yes, that's correct. And that's pretty much all there is to it, too - each function invocation creates a new scope. The "closure" is really just a function scope that you can pass around and access when you call the internal unnamed function. – VLAZ Mar 06 '19 at 11:22
  • Thank you @VLAZ. Is there any resource you know of that explains the internals of how the JS engine creates scopes? I'm looking for a deeper understanding of what the book "You Don't Know JS" provides. – zebedee Lewis Mar 06 '19 at 16:04

1 Answers1

0

Each time you invoke test2 the engine creates a new closure.

If you want to re-use the same closure, then you also have to use the same variable:

function test2() {
  var a = Date.now();
  return function() {console.log(a)}
}

var b = test2();
b();
b(); // the same
  • So would I be correct to conceptualize it as the following: the scope is like the class definition and the closure is like an instantiation of the scope? – zebedee Lewis Mar 06 '19 at 15:38
  • I don't advise you to think like that. Don't think about class and objects because that's another level of abstraction. Let's just say that every closure keeps its scope (it has its own local variable) and they don't mutate until you access directly in the closure – Christian Vincenzo Traina Mar 06 '19 at 22:02