DEV Community

K
K

Posted on

JavaScript Closes

When I started with JavaScript, most of my coding experience came from PHP, C and Java. So when I saw the first snippets of JavaScript, it looked like Voodoo to me. Functions defined here and there, put into variables, moved around and they even used variables that didn't seem to belong to them.

Who calls these functions?

Where do they get their variables from?

I don't even...

Introducing Closures

So you probably read about closures are a thing in JavaScript. Well, they are probably the main thing.

First: Functions

So what is needed to understand them?

You are probably used to simple static(?) function definitions from other languages. They exist in JS too.

function f(x) {
  return x + 10;
}

f(10); // -> 20
Enter fullscreen mode Exit fullscreen mode

But there are also function expressions.

An expression is a language construct that (kinda) return something, you say they evaluate to something. if or for, for example aren't expressions, you cant write let x = if (b > 10) .... A function call, a calculation or a comparison are expressions.

f(10); // returns something -> 20
10 * 3; // evaluates to 30
10 === 3; // evaluates to false 
Enter fullscreen mode Exit fullscreen mode

In JS not only function calls, but also their definitions can be expressions.

let f = function myFunction() {}; // evaluates to a reference to the function myFunction

let g = function () {}; // The function doesn't even have to have a name
                        // because we can call it via its reference stored in g

g();
Enter fullscreen mode Exit fullscreen mode

This allows us to define functions somewhere save, store it in a variable and send it around our application, for example if you want to use it as a callback.

let f = function () {}; // store function reference

window.addEventListener("load", f); // call it when something happens
Enter fullscreen mode Exit fullscreen mode

As you know from other languages, there are global and local variables.

x = 20;

function f(y) {
  let z = 10;
  return x * y * z;
}
Enter fullscreen mode Exit fullscreen mode

In the example x is defined without var, let or const so it will become a global variable. In JS this means it will be attached to the global window object in browsers. Global variables can be accessed anywhere, for any function, so we can use it inside f().

Second: Closures

What has this to do with closures?

Well closures are functions that close over or capture their definition context. Which sounds kinda cryptic, but means something like, they can use the variables that are defined around them.

It's a bit like globals.

x = 10; // global

function f() { // -- definition context of g
  let y = 20; // local to f, but g has access

  let g = function (z) {
    return x * y * z; // global * context * local
  }

  return g;
}              // -- end of g's def. context

function h(a) {  
  return x * a; // no access to y, just global and local
}

let newG = f();

newG(2);
Enter fullscreen mode Exit fullscreen mode


`

Why would you use this? For callbacks, for example.

Imagine you want to access some non-global data, but the functions you pass as callbacks won't receive this data.

`javascript
let user = {name: "kay-is"};

// the function passed to setTimeout won't get any arguments
// but it has access to the variables "around" its definition
setTimeout(function (alwaysUndefined) {
alert(user.name) // alert is global
// user is local to the parent scope
}, 100)
`

Or imagine, you have some data, that shouldn't be modified.

`javascript
function ReadOnly(user) {
// the parameter is local to ReadOnly
// getName and getAge are closures that can access them
return {
getName: function() { return user.name; },
getAge: function () { return user.age; }
}
}

// somewhere save
let peter = {name: "Peter", age: 43}
let readOnlyPeter = ReadOnly(peter);

// code with access to peter can modify the object
// code with access to readOnlyPeter can't modify it
readOnlyPeter.getName();
readOnlyPeter.getAge();
readOnlyPeter.name = "Franz"; // readOnlyPeter doesn't have this attribute.
`

Conclusion

Closures could be called the bread and butter of JavaScript. JavaScript is an event based system where almost everything is handled asynchronously by callbacks, even promises or observables are just abstractions over this fact.

They allow to write code without the need of globals, but still maintain a bit of the light-weight feeling globals bring to programming.

Top comments (0)