Is It True That Every Function in JavaScript Is a Closure

Is every function a closure?

closure is a function that has references to variables/methods outside its definition

No, this is a "function with free variables", not a "closure".

To quote wikipedia

...a closure is only distinct from a function with free variables when outside of the scope of the non-local variables, otherwise the defining environment and the execution environment coincide and there is nothing to distinguish these (static and dynamic binding can't be distinguished because the names resolve to the same values).

In other words, in some context, a closure is a reference to a function that binds variables from another context. Otherwise, it wouldn't make sense to call it a "closure".

Is every function in JS a closure

A closure is created by calling a function; the function itself isn't the closure. Conceptually, every function call implicitly causes a new closure to come into existence. For some functions, the closure is ephemeral and just vanishes as soon as the function returns:

function add2(n) {
return n + 2;
}

That function returns only a number; nothing can refer to anything in the closure created by the function call, so the closure goes away and all you have left is the return value.

The closure becomes interesting when a function returns something that has one or more "hooks" into the local environment created when the function was called. (The function can expose the closure by modifying the global environment too.) So this function:

function addn(addend) {
return function(n) {
return n + addend;
}
}

exposes the closure because the returned function has a reference to the parameter of the outer function.

I can't think of a way an ordinary function can expose a closure that doesn't somehow involve one or more functions that reference stuff from the local context (parameters, variables). (Generator functions are interesting, because yield kind-of always returns something that exposes the closure, I suppose.)

Is it true that every function in JavaScript is a closure?

Is the function created by Function constructor also a closure?

Yes, it closes over the global scope. That might be unintuitive because all other JavaScript closures close over their lexical scope, but it still matches our definition of a closure. In your example, a is a free variable, and resolves to the a in an other scope when the inner/fn function is called somewhere.

If an inner function doesn't have any free variables, can we still call it a closure?

Depends on whom you ask. Some say Yes, others call them "uninteresting closures", personally I say No because they don't reference an outer scope.

Is this really considered a javascript closure?

I think we can agree that a function doesn't have to be defines inside another function to be a closure. I'd probably have followed up and asked why they think that that's a requirement for being a closure and then direct the conversation towards scope in general.

People may have different opinions about what really constitutes a closure, but I like the description from Wikipedia (which used to be a bit more extensive) which I have been using whenever I teach JavaScript:

Operationally, a closure is a record storing a function together with an environment.

I like it because it is a very easy to understand description, and it applies easily to JavaScript functions, because that's exactly how it works as described in the spec. The spec even uses the term closure to refer to a created function, irrespectively of the actual content of the function.

And following that thought, every function in JavaScript is a closure, so you are right.

Having said that, I could see someone making the argument that this function is not used as a closure, since it doesn't access any free variables.


I also have to add that "closure" wouldn't be the first thing that comes to my mind when looking at this code. It's easier to name the things that are there vs that are not there (referring to the function not be used as a closure).

The first thing that would come to my mind is function expression.

How do JavaScript closures work?

A closure is a pairing of:

  1. A function and
  2. A reference to that function's outer scope (lexical environment)

A lexical environment is part of every execution context (stack frame) and is a map between identifiers (i.e. local variable names) and values.

Every function in JavaScript maintains a reference to its outer lexical environment. This reference is used to configure the execution context created when a function is invoked. This reference enables code inside the function to "see" variables declared outside the function, regardless of when and where the function is called.

If a function was called by a function, which in turn was called by another function, then a chain of references to outer lexical environments is created. This chain is called the scope chain.

In the following code, inner forms a closure with the lexical environment of the execution context created when foo is invoked, closing over variable secret:

function foo() {
const secret = Math.trunc(Math.random() * 100)
return function inner() {
console.log(`The secret number is ${secret}.`)
}
}
const f = foo() // `secret` is not directly accessible from outside `foo`
f() // The only way to retrieve `secret`, is to invoke `f`

Will a simple function declaration form a closure in JavaScript?

Yes, it forms a closure.

A closure is the combination of a function reference and the environment where the function is created. The code in the function will always have access to any variables defined in the scope where the function is created, no matter how the function is called.

Example; the function f will always use the variable x even if it is called in a scope where x isn't reachable:

function container() {
var x = 42;
function f() { document.write(x); }
return f;
}
var func = container();func(); // displays 42//document.write(x); // would give an error as x is not in scope


Related Topics



Leave a reply



Submit