// A closure is a function having access to the parent scope,
// even after the parent function has popped.
function greeting() {
let message = 'Hi';
function sayHi() {
console.log(message);
}
return sayHi;
}
let hi = greeting();
hi(); // still can access the message variable
function makeAdder(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
//my words: what this code do is basically a nested function that will return
//its inner function (un-activated). So var add5 in line 7 activated the outer
//function with 5 as parameter which makes add5 is now the nameless function at
//line 2 that will return 5 + y;
//MDN words:
//add5 and add10 are both closures. They share the same function body
//definition, but store different lexical environments. In add5's lexical
//environment, x is 5, while in the lexical environment for add10, x is 10.
function makeAdder(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
//=====
//add5 and add10 are both closures.
//They share the same function body definition, but store different lexical environments.
//In add5's lexical environment, x is 5, while in the lexical environment for add10, x is 10.
// global scope
var e = 10;
function sum(a){
return function(b){
return function(c){
// outer functions scope
return function(d){
// local scope
return a + b + c + d + e;
}
}
}
}
console.log(sum(1)(2)(3)(4)); // log 20
// You can also write without anonymous functions:
// global scope
var e = 10;
function sum(a){
return function sum2(b){
return function sum3(c){
// outer functions scope
return function sum4(d){
// local scope
return a + b + c + d + e;
}
}
}
}
var sum2 = sum(1);
var sum3 = sum2(2);
var sum4 = sum3(3);
var result = sum4(4);
console.log(result) //log 20
function numberGenerator() {
// Local “free” variable that ends up within the closure
var num = 1;
function checkNumber() {
console.log(num);
}
num++;
return checkNumber;
}
var number = numberGenerator();
number(); // 2
/*
A lexical environment is part of every execution context (stack frame) and is a map between identifiers (i.e. local variable names) and values.
Every function in JavaScript maintains a reference to its outer lexical environment. This reference is used to configure the execution context created when a function is invoked.
This reference enables code inside the function to "see" variables declared outside the function, regardless of when and where the function is called.
If a function was called by a function, which in turn was called by another function, then a chain of references to outer lexical environments is created.
This chain is called the scope chain.
In the following code, inner forms a closure with the lexical environment of the execution context created when foo is invoked, closing over variable secret:
*/
function foo() {
const secret = Math.trunc(Math.random() * 100)
return function inner() {
console.log(`The secret number is ${secret}.`)
}
}
const f = foo() // `secret` is not directly accessible from outside `foo`
f() // The only way to retrieve `secret`, is to invoke `f`
Run code snippet
// javascript closure example
// outer function
function greet() {
// variable defined outside the inner function
let name = 'John';
// inner function
function displayName() {
// accessing name variable
return 'Hi' + ' ' + name;
}
return displayName;
}
const g1 = greet();
console.log(g1); // returns the function definition
console.log(g1()); // returns the value
/*A closure is the combination of a function bundled together (enclosed) with references
to its surrounding state (the lexical environment). In other words, a closure gives you
access to an outer function’s scope from an inner function. In JavaScript, closures are
created every time a function is created, at function creation time.*/
function init() {
var name = 'Mozilla'; // name is a local variable created by init
function displayName() { // displayName() is the inner function, a closure
alert(name); // use variable declared in the parent function
}
displayName();
}
init();