Ad

Are Global/Nested Functions In JavaScript Implemented As Closures?

- 1 answer

I'm working on an school assignment comparing higher-order function/closure implementation in Swift and JavaScript.

Apple documentation explicitly mentions global and nested functions in Swift as a special case of closures, but I have been unable to find any similar/conflicting information about their implementation in JavaScript.

A cursory search returned this blog post which suggests that the global scope in JS is implemented as a closure, but I can't seem to find solid evidence which I would be comfortable including in my report. (Most searches simply return overviews of JS closures/scoping which aren't useful to me.)

If any JS gurus are familiar enough with this implementation I'd really appreciate the information.

Cheers!

Ad

Answer

Lexical Scoping


Dictionary defines lexical as "pertaining to words or vocabulary of a language". Lexical scope of a function in JavaScript is statically defined by the physical placement of the function in the code.

var a = "Top of all";

function first(){
 var b = "I am first";
  function second(){
   var c = "I am second";
   }
}

This forms a lexical hierarchy:

global --> first --> second

variableEnvironment Read 10.4 and 10.5

Every possible scope in JavaScript has its own execution context. Each execution context has its own variableEnvironment - This is the place where all the variables of that context live. Every invocation of a function establishes and enters a new execution context and hence a new variableEnvironment.

Take Away: Each variableEnvironment will also inherit the variableEnvironment of its immediate lexical scope.

I can also frame it in this way: Each variableEnvironment inherits the variableEnvironment of the context that created it.

So for the example above, first inherits variableEnvironment of global, and second inherits the variableEnvironment of first.

How does this inheritence work?


During the execution, whenever a new function is called, a new execution context is created, hence a new variableEnvironment is created. This new variableEnvironment has a property called outerLex, which holds the variableEnvironment of the lexical scope that created it.

So how does the variableEnvironment for the function second in our example look like?

{
 c: ... // own variables
 outerLex: {
   b: .. // variables of outer lexical scope
   outerLex: {
      a: .. // global variable
   }

 }
}

Does it start to make sense? This also should explain why variables are "shadowed" when they are present with the same name in different scopes.

Also notice that the variables are prioritized by lexical proximity.

I have already explained closures. All theory you have read elsewhere should start making sense.

The innermost variableEnvironment has an outerLex property which references the variableEnvironment above it, and thus preventing variables of outer scope from being garbage collected. Garbage collection works by checking how and which elements are referring what elements. Read more here

Even if the function first has returned and ended execution, function second can still validly refer to the variable b defined in it, because it has a reference to its variableEnvironment.

Let's dig deeper (and also answer your question)


When a function is created, the variableEnvironment is inherited automatically. And we already saw above that inheritence of variableEnvironment creates a function closure.

So, A closure is formed on function creation and it has nothing to do if the function has returned or not (common myth)

Also, JavaScript objects work through reference.

So, outer variables are referred, and not copied in the variableEnvironment

Answer to your question


Each and every function creates a closure in JavaScript. It is a common misunderstanding that only inner functions create closure, which is not the case.

Functions in global scope also form closures, but their closure is boring, because it only references the global variableEnvironment, which is visible in any case.

Finally, you say you need a document to link for your homework. This should suffice ;)

[Edit]: I hate terminology. Whenever the outerLex property is empty, some people like to say that a closure is not formed. Meh.

[Edit 2]: Most of what is written in this article is contrary to what is floating on the web. Kindly read the ECMA-262 standard to support any of your claim.

Ad
source: stackoverflow.com
Ad