Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are these considered to be Javascript closures?

Wanting to get something straight here...so I have 2 questions

The function below creates a closure.

function Foo(message){
    var msg = message;

    return function Bar(){ 
        this.talk = function(){alert(msg); }
    }
};

Q: Which function is the closure, Foo or Bar?
I always thought the closure to be Foo, because it closes-over Bar once Bar is returned.

Next...

Below is the definition of an anonymous function:

()();

Q: Is the inner-function within this anonymous function also a closure?

(function(){ /* <-- Is this function also a closure? */ })();
like image 912
Prisoner ZERO Avatar asked Aug 20 '12 14:08

Prisoner ZERO


People also ask

What are the closures in JavaScript?

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function.

Are all js functions closures?

But as explained above, in JavaScript, all functions are naturally closures (there is only one exception, to be covered in The "new Function" syntax). That is: they automatically remember where they were created using a hidden [[Environment]] property, and then their code can access outer variables.

Why are closures important in JavaScript?

In their simplest form, closures are functions with preserved data. A closure is created every time a function is created. Closures give us the ability to store data in a separate scope and access it only when necessary. A simple reason why we need closures is to give some of our data privacy.

Are callbacks closures?

a callback is executable code that is passed as an argument to other code. a closure is a function that is evaluated in an environment containing one or more bound variables. When called, the function can access these variables. a callback is executable code that is passed as an argument to other code.


1 Answers

You need to use first principles here. Javascript uses lexical scoping. This means the scope of an execution context is determined by how the code is defined (lexical).

I would say the definition of the function Bar is what causes the closure to be created, because msg is "closed-in" in the function.

The actual creation of the closure happens at runtime (which is somewhat of a tautological statement, since nothing in a computer program happens until it is run), because in order to determine the value of msg, in Bar, when Bar is executed, the interpreter needs to know the value of the variable when Foo is executed, and so on up the chain.

I'll give two answers to your question. The pedantic answer is: neither function by itself is the closure. It's the definition of variables within functions, combined with the execution context of functions when they are run, that is defines the closure. The common answer is: any function which closes over a variable is a closure (Bar in your case).

Consider the problem everyone encounters when using Javascript.

function A(x) {
   var y = x, fs = [];

   for (var i = 0; i < 3; i++) {
       fs.push(function(){
         console.log (i + " " + x);
       })
   }

   fs.forEach(function(g){g()})  
}

A('hi')

Most people would say this would produce the output 'hi 1' followed by 'hi 2' followed by 'hi 3'. However, it produces 'hi 3' 3 times. If just the definition of the function being added to the array, while using variables defined in the outer function, created the closure, how can this be?

It's because you need the execution context to define the closure, which doesn't happen until runtime. At the execution of the functions in the array, i has the value 3. In the forEach statement, that's the execution context, which is why the output always uses 3.

like image 132
hvgotcodes Avatar answered Sep 18 '22 22:09

hvgotcodes