JSFiddle - React, Tailwind, and code Playground
JavaScript
//A brief overview of closures
var makeClosures = function(){
var a = 1;
// 1. Functions can "see" their surrounding scope. In this example, `a` is accessible even though it's declared outside the function.
// The combination of the function and the variables it has in scope is called a "closure".
var printA = function(explanation){
console.log(explanation, a);
};
printA("a is available inside the function."); //=> 1
// 2. What the function "sees" is just a variable. The `a` accessible inside of `printA` is the same `a` as outside of it. It's
// not a copy nor is it "capturing" the *value* or anything like that; you're just using the enclosing binding of `a`. For example,
// if we reassign `a` outside the function, `printA` "sees" the change:
a = 2;
printA("a's value can be updated."); //=> 2
// We can even change its value from inside the function. You generally should not do this because it's confusing.
var incA = function(){
a = a + 1;
};
incA();
printA("a's value can even be updated in a closure"); //=> 3
return [printA, incA];
};
[printA, incA] = makeClosures();
// 3. Variables live as long as the closures that contain them do. That's what we mean when we say variables are "captured":
// that the language can't throw them away and garbage collect their values because the closure is "holding on" to them. Here,
// `a` is unbound, but `printA` still lives and it still knows all about `a`:
console.log("a is undefined here.", typeof(a)); //=> undefined
printA("a is still bound inside of printA."); //=> 3
//4. Closures are lexical. That means the answer to "what does `a` refer to?" depends only on what `a` means where `printA` is
// *defined*, not where `printA` is *used*. (Lexical means "of the text"). Defining `a` at the call site has no effect:
var a = 6000;
printA("a ignores variables at the call site"); //=> 3
// Compare this to dynamic scoping (dynamic meaning "contigent on...