Closures
Simply a function that refers to variable in its parent scope.
Example 1:
//We create a clojure each time we invoke lessThanFilter
function lessThanFilter(lessThen){//Create a scope here
//The function we are returning is a clojure, and it has a scope.
//But it also takes the scope of the lessThanFilter()
return function(item){ //This create another scope
//item is bound to the parameter of the clojure
return item < lessThan; //lessThan is bound to the parameter of the lessThanFilter
}
}
//Everytime we invoke the lessThanFilter, we get a new instantiation of the lessThanFilter scope.
//It does have a lexical scope, so this makes two instances of the clojure:
var lessThanFive = lessThanFilter(5);
var lessThanTwo = lessThanFilter(2);
lessThanFive(2); -> True
lessThanTwo(1); -> True
Example 2:
We want to emphasis that is the difference with the lexical scope and the scope at runtime
function validatePassowrd(password) {
var calledCount = 0;
return function(attempt){//This is a closure as we are referencing calledCount
calledCount ++;
console.log(Validator of + password + called + calledCount + times);
return attempt === password;
}
}
var validateA = validatePassword("passworda");
var validateB = validatePassword("passwordb");
validateA("invalid"); -> Validate of password called 1 times
validateA("invalid"); -> Validate of password called 2 times
validateA("invalid"); -> Validate of password called 3 times
validateB("invalid"); -> Validate of password called 1 times
validateB("invalid"); -> Validate of password called 2 times
By having this function expression (return function(attempt):
- We are getting a scope of both its scope and its parent function.
- We have two instances of the calledCount variable one in closure (validateA) and one in (validateB)
Example 3:
- Each time we call a function, a new block of memory is allocated.
- Memory will stick around.
function example() {
var a = 20; //Still in existence by the closure.
return inner1();
function inner1(){
var b = 30;
return inner2();
function inner2(){
var c = 40;
return function() {
console.log(a,b,c); -> 20 30 40
};
}
}
}
var clojure = example();
clojure();