DEV Community

Cover image for JavaScript Function Closures
Bello Osagie
Bello Osagie

Posted on • Edited on

JavaScript Function Closures

image.png


A global variable in the global scope can also be used in a local scope. This means expressions in a local scope can reach out to variables in a global scope.

See the example below:

const name = 'Bello'; // global variable

const outerFunc = () => {
    console.log(`My name is ${name}.`); 
     // global variable in a local scope
};

const outer = outerFunc(); 
outer; // My name is Bello. => global variable
Enter fullscreen mode Exit fullscreen mode

Below is another example:

const outerFunc = () => {
  const outerScope = "outer scope";

  const innerFunc = () => {
    console.log(outerScope);
  };

  // console.log( innerFunc() );
  return innerFunc()
};

const outer = outerFunc();
outer; // outer scope
Enter fullscreen mode Exit fullscreen mode

Let's omit the parenthesis — return innerFunc not return innerFunc().

With closure, a global variable can be made local.

See the example below:

const outerFunc = () => {
  const outerScope = "outer scope";

  const innerFunc = () => {
    const outscopeInLocalScope = outerScope;
    console.log(outscopeInLocalScope);
  };

  return innerFunc;
};

const outer = outerFunc();
outer; // [Function: innerFunc]
Enter fullscreen mode Exit fullscreen mode

innerFunc function has access to both its own scopes (e.g variables outscopeInLocalScope) and the outer scope (e.g variables outerScope). The function in closure above is innerFunc.

Closure makes the innerFunc() have access to the outerFunc, but the outerFunc() has no access to the innerFunc.

[Function: innerFunc] is returned because the innerFunc function has to be returned from the outerFunc function before being executed - outerFunc()().

// outerFunc()();

const outer = outerFunc();
outer(); // outer scope
Enter fullscreen mode Exit fullscreen mode

Check out the alternative way to return a closed function (any function though) return innerFunc... below:

const outerFunc = () => {
  const outerScope = "outer scope";

  let innerFunc;
  return innerFunc = () => { 
    const outscopeInLocalScope = outerScope;
    console.log(outscopeInLocalScope);
  };

};

const outer = outerFunc();

outer; // [Function: innerFunc]
outer(); // outer scope
Enter fullscreen mode Exit fullscreen mode

Helper Nested Function

The helper function helps prevent scope pollution. For example, it prevents duplicate variables in a global scope (global namespace) and makes your code more organized, maintainable, and easier to read. If bugs arise, it becomes easier to debug.

Let's pass arguments to parameters:

const outerFunc = x => {
  const a = x;

  const innerFunc = y => { 
    const b = y;
    return a * b;
  };

  return innerFunc;
};

const helperFunc = () => {
  const outer = outerFunc(4);
  outer; // [Function: innerFunc]
  console.log( outer(3) ); // outer scope
};

helperFunc(); // 12 
Enter fullscreen mode Exit fullscreen mode

The helper function above is the same as below:

const helperFunc = () => {
  const outer = outerFunc(4)(3);
  console.log(outer); 
};

helperFunc(); // 12 
Enter fullscreen mode Exit fullscreen mode

We can pass arguments to the parameters as well in the helperFunc function.

const helperFunc = (i, o) => {
  const outer = outerFunc(i); // i = a
  outer; // [Function: innerFunc]
  console.log( outer(o) ); // i * o => o = b
};

helperFunc(3, 4); // 12
Enter fullscreen mode Exit fullscreen mode

The helper function above is the same as below:

const helperFunc = (i, o) => {
  const outer = outerFunc(i)(o);
  console.log(outer); 
};

helperFunc(3, 4); // 12 
Enter fullscreen mode Exit fullscreen mode

Happy coding


image.png


image.png

Top comments (0)