netdeveloper62
netdeveloper62

Reputation: 351

Why does closure matters?

What is advantage of closure vs class, and why closure has advantages? Class has data and behavior/methods that operates upon these data. If anyone can answer me this question? I am coming from OOP background, and I don't see that paradigm "code as data" so clear. Is it composition in functional languages that matters?

Thanks.

Upvotes: 0

Views: 97

Answers (2)

Mark Westling
Mark Westling

Reputation: 5974

You can put variables in a class (in many languages, anyway) but then the functions on that class share the exact same set of variables. You could also create an object to hold the variables and define the function on the object, but then the primary "thing" of interest is the object, whereas you might not care about the variables (except when you first initialize them), only the function.

Let's say you want to create functions at runtime that do basically the same thing but with different variables (e.g., each function spits out the next value of a collection that's given to it when the function is defined). You can't do it with class variables and a class function (method) because the class variables are shared (i.e., you have only one function and it works on a single collection at a time).

You could create an object that holds the initial value (i.e., the collection) and define a function on the object that references those values. If what you really want is a function, though, then this object might seem unnatural: after all, you're carrying around an object to hold your collection, a pointed to the next element to emit, and the function to emit it, whereas you just want a function.

A closure is a natural way of creating such a function. When you create the closure, it gets a private set of variables that retain their value between function calls, but these variables (the referencing environment) are hidden. If you tried to implement the same thing with an object, you'd be dealing with the object first and your function second, even though the "thing" of interest to you is the function (and once you're initialized those variables, you don't care about them).


Here's a use case: callbacks.

Suppose you want to use the same callback function in many places and at many times, but you want it to be called not just with the event object but also some data to specify when you set it up. For example, suppose your function is called myFunc(event) and when it's called, you want it to log a string that you pass, so you really want to define it as myFunc(event, string_to_be_logged), like this:

function myFunc(event, string_to_be_logged) {
  ...do stuff...
  log(string_to_be_logged);
}

The framework that invokes the callback expects a function and nothing else and invokes it with just the event object. If you only do this once or twice, you might define two versions of your callback:

function myFuncABC(event) {
  ...do stuff...
  log("ABC");
}

doSomethingAsyc(&myFuncABC);   // pass the pointer to the callback function

function myFuncDEF(event) {
  ...do stuff...
  log("DEF");
}

doSomethingAsyc(&myFuncDEF);

but you can see the problem with this!

Instead, we can create the callback function dynamically, as a closure:

function createCallback(str) {
  var myFunc = function(event) {
                 ...do stuff... 
                 log(str);
               }
  return myFunc;
}

Tthe function we're generating is a closure because it retains its referencing environment: the str variable. Every callback function we generate this way gets its own private copy of str.

Now, we can do the following:

var mf1 = createCallback("ABC");
doSomethingAsyc(myFunc);    // pass the variable containing the callback function
var mf2 = createCallback("DEF");
doSomethingAsync(mf1);

and the first callback will log "ABC" while the second one logs "DEF".

Upvotes: 0

TGH
TGH

Reputation: 39248

The main advantage is that it enables you to create private scope and avoid affecting code outside of the closure by introducing global variables etc. It's a very common pattern to use in JavaScript.

Upvotes: 1

Related Questions