//Higher order functions:-
//========================
function fun() {
console.log('inside fun');
let x = 0;
function innerFun() {
x++;
console.log(x);
}
return innerFun;
}
let f = fun(); //Output: inside fun
f(); //Output: 1
f(); //Output: 2
f(); //Output: 3
f(); //Output: 4
f(); //Output: 5
console.log('\n\n\n\n');
//Closures:-
//==========
console.log('Closures:\n\n');
var add = (function () {
var counter = 0;
return function () {counter += 1; return counter}
})();
console.log(add());
console.log(add());
console.log(add());
// the counter is now 3
//What does this mean?
//The variable add is assigned to the return value of a self-invoking function.
//The self-invoking function only runs once. It sets the counter to zero (0), and returns a function expression.
//This way add becomes a function. The "wonderful" part is that it can access the counter in the parent scope.
//This is called a JavaScript closure. It makes it possible for a function to have "private" variables.
//The counter is protected by the scope of the anonymous function, and can only be changed using the add function.
//=>A closure is a function having access to the parent scope, even after the parent function has closed.