Skip to content

Instantly share code, notes, and snippets.

@DeepNeuralAI
Last active May 29, 2019 09:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DeepNeuralAI/4bfc54916b961a72cca4325069dacf28 to your computer and use it in GitHub Desktop.
Save DeepNeuralAI/4bfc54916b961a72cca4325069dacf28 to your computer and use it in GitHub Desktop.
Closures

Javascript - Closure

“Writing in JS language without understanding closure is like writing Java without understanding classes”  — Douglas Crockford, father of JSON

Introduction

interview

You've been working as a junior developer for awhile, and you're finally ready to apply for your next developer job.

You're sitting at the interview and it's going well. You know Javascript pretty well.

Then they ask, "Explain the topic of closures"

You freeze. Your heart starts beating faster. You blurt out "is it hot in here or is it just me?"

The interviewer looks puzzled at you.

One drop of sweat collects on your forehead and slowly rolls down. Right into your eye.

Now you're squinting at the interviewer. You then start worrying if he thinks you're winking at him profusely.

You (attempt to) channel your inner Beyonce, but you end up looking like an absolute clown.


Your friend Felicia asks you how the interview went.

This. This is how it went Felicia.

What was the point of that story?

I'm not sure. But let's talk about closures.

Closures

Closures is one of those topics that scares people, but there is no reason to be.

People often overexplain it, making it sound more complicated than it is.

We can also do some cool stuff with it, like emulating private methods.

Example:

let x = 0;

const addNumber = () => {
  return 3 + x;
}

console.log(addNumber);

Why is this not efficient?

It uses global scope, and there is nothing to protect it against change.

We often forget that javascript is a lexical scoping language. That's a really snobby way of saying that inheritance flows inwards

A variable outside a function is available for use within a function, but not the other way around.

You can not use a variable inside a function, outside it.

Basic Closure Example

function outside() {
  let x = 2;
  return function inside(y) {
    return x * y;
  }
}

If we call outside() what do we get?

image

When we call outside(), we get another function returned, in this case inside

What if we call outside()(4) we pass in 4 to the inside function.

outside()(4)
// 8

The double parenthesis looks weird, so some people like this way better:

const myClosureFunction = outside();
myClosureFunction(5)
// 10


myClosureFunction(5) === outside()(5)
// true 

What about x?

Source: A Beginner’s Guide to Understanding JavaScript Closures

The best part of a closure is x, because we have created a variable that no other part of our program can touch, but we can still use.

This is the power of closures: it lets us create values that can’t be altered or accessed by any functions other than the closure itself.

The reason this works is because scopes can access values in their parents, but not their children. x is defined in the parent scope of inside, so inside can still access it and multiply it by y.

However, the only thing that gets exposed to the global scope is the definition of inside, not the variable x.

That means in our entire program, the only way we can interact with x is by using the closure.

Non-closure Example:

let x = 2 //global scope

function inside(y) {
  return x * y //taking x from global
}

inside(4)
// 8

// We can alter x
x = 5 
inside(4)
//20

Closure Example:

function outside() {
  let x = 2;
  return function inside(y) {
    return x * y;
  }
}

const myClosureFunction = outside();
myClosureFunction(5)
// 10

x = 4
myClosureFunction(5)
// 10

// Notice how it's still 10. The x inside the closure is different than the x outside

x is defined in our outside function, so anything outside can not reach down into it and change it.

When we tried to reassign x to the value 4, JS saw that as a completely different x.

Last Example

function adder(x) {
  return function(y) {
    return x + y
  }
}

let add5 = adder(5);
let add10 = adder(10);

console.log(add5(2)); // 7
console.log(add10(2)); // 12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment