3

From every definition I have looked up, closure is when a function is created or declared from within another function. Examples are plentiful across blogs and websites of this happening. But what about when the function is declared outside of another function, but called then called from within a function? For example:

const add = (x,y) => {
  return x + y;
};

const double = num => {
  return add(num,num)
};

let a = double(6);/*?*/

Does add(num, num) create closure? If so, please help me understand why.

  • No, there is no function created in the call `add(num, num)`, (nor in the call `double(6)`), so there is no closure. – Bergi Dec 21 '17 at 23:20

1 Answers1

2

Closures are a product of lexical scope.

A closure is the combination of a function and the lexical environment within which that function was declared.

You must define a function within another one to create a closure.

What you do in your example is simply call a function that calls another and uses its return value. At no point can the double function access the scope of the add function: their scopes are distinct.

Here is a classical example of JavaScript closure

var makeAdder = function(x) {
    return function(y) {
        return x + y;
    };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

In both cases, the functions returned by makeAdder, "remember" the outer scope in which the were created (the scope created by the makeAdder function).

Anything that was in scope of the outer function was also in scope for the inner function, and it remains so when the inner function is returned.

Sébastien
  • 11,860
  • 11
  • 58
  • 78
  • Can you help me understand why here: https://stackoverflow.com/questions/615907/how-is-a-closure-different-from-a-callback they state that a call back function using context variables is a closure? – Chase Norton Dec 21 '17 at 22:11
  • Which would seem to indicate that if I write the above as const add = (x,y) => { return x + y; }; const double = (num, func) => { return func(num,num); }; let a = double(6, add);/*?*/ Then closure is created – Chase Norton Dec 21 '17 at 22:12
  • @ChaseNorton That doesn't create a closure. `double` is just calling a callback. You get a closure when you do `return function(...) { ... }` – Barmar Dec 21 '17 at 22:20
  • @Barmar He does return a function. But, to the point: yes ChaseNorton you create a closure but you don't take advantage of it so to speak because you never use the context from outside the function. Check out the first exemple on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures – Sébastien Dec 21 '17 at 22:22
  • 1
    @Sébastien He doesn't return a function. `double` calls the callback, it doesn't return a function that calls the callback. – Barmar Dec 21 '17 at 22:27
  • So @Sébastien, in a technical sense - closure is created but just not taken advantage of in the original example? – Chase Norton Dec 21 '17 at 22:27
  • 1
    @ChaseNorton The distinction between function and closure is only significant if you define the function in the scope of another function, and it accesses local variables of that function. – Barmar Dec 21 '17 at 22:28
  • @Barmar, you marked this as duplicate, but I feel I am asking a different question of if calling a function creates closure. – Chase Norton Dec 21 '17 at 22:28
  • 2
    All functions are technically closures, but if it doesn't capture local variables it's not interesting. – Barmar Dec 21 '17 at 22:29
  • @Barmar, while it may be only significant in that sense - is it still the fact that it creates closure? From my understanding, closure exists when you allow a function to access scope that it originally did not have access to. – Chase Norton Dec 21 '17 at 22:30
  • @Barmar , yes of course, you were correct. – Sébastien Dec 21 '17 at 22:30
  • Anyway @ChaseNorton look at my new example but mostly read the MDN and just play with it, try for yourself. – Sébastien Dec 21 '17 at 22:32
  • 1
    @ChaseNorton I don't know what you mean by "scope that it originally did not have access to". If it's defined within the scope, it has access to it. What makes it a closure is when you return it outside the scope, so it captures that environment. – Barmar Dec 21 '17 at 22:32
  • I still consider this a duplicate. If you read and understand the first question, it should explain all you need to know about how closures work. If there's something that isn't clear there, you should comment on that question so it can be improved. – Barmar Dec 21 '17 at 22:33
  • Yes, that question has been asked many times in different forms... – Sébastien Dec 21 '17 at 22:35
  • Sounds good. Thank you for your input – Chase Norton Dec 21 '17 at 22:37
  • So in reading more into this - it seems that technically - add within double is a closure. Since both add and double do not use any global variables and thus do not provide any closure - we can not consider the functions themselves to be closures. So in this case, there would be 1 closure with add(num, num) - but there would be two closures if for instances the code was written as let number = 4; const add = (x,y) => { x += number; return x + y; }; const double = (num) => { return add(num,num); }; let a = double(6);/*?*/ It may not be the – Chase Norton Dec 22 '17 at 00:42