In-depth understanding of the nine usage scenarios for JS closures
1 Return value (most commonly used)
// Return name as a closure.
function fn(){
let name = "hello"
return function(){
returnname; }}let func = fn(); // call the function
console.log(func());// Call again, print hello
Copy the code
2 function assignment
Set the value of the fn2 function in a closure that memorizes the name property and prints Hello
let fn2;
function fn(){
let name= "hello"
// Assign the function to fn2
fn2 = function(){
return name;
}
}
fn() // Perform the assignment first
console.log(fn2());// Execute output fn2, which is hello
Copy the code
3 Function Parameters
Use closures to return a function, take that function as an argument to another function, execute that function inside another function, and finally print Hello
function fn(){
let name = "hello"
return function callback(){
returnname; }}let fn1 = fn() // The callback function assigns the return value to fn1
function fn2(f){
// Pass the function as an argument
console.log(f()); // Execute the function and print it
}
fn2(fn1) // Call the function
Copy the code
4.IIFE (self-executing function)
Passing fn1 as an argument to fn2 directly from the self-executing function also results in Hello
(function(){
let name = "hello";
let fn1 = function(){
return name;
}
// Call fn2 directly from the self-executing function, passing fn1 as an argument
fn2(fn1)
})()
function fn2(f){
// Function groups are passed in as arguments
console.log(f());// Execute the function and print it
}
Copy the code
5 Loop assignment
// Execute once per second, output 1-10 respectively
for(let i = 1; i <=10; i++){
(function (j) {
setTimeout(function() {
console.log(j);
},j*1000)
})(i)// I is passed as an argument
}
Copy the code
6 getter and setter
By first printing Hello and then world with setter, you can encapsulate it as a public method, preventing unwanted properties and functions from being exposed externally.
function fn() {
let name = "hello"
setName = function (n) {
name = n;
}
getName = function(){
return name;
}
// return setName, getName as properties of the object
return {
setName:setName,
getName:getName
/ / short
//setName,getName}}let fn1 = fn()SetName and getName are two functions
console.log(fn1.getName());//getter
fn1.setName('world');// setters modify the name inside closures
console.log(fn1.getName());//getter
Copy the code
7. Iterators (perform a function once to fetch a value down)
let arr = ["aa".'bb'.'cc']
function increment(arr){
let i = 0;
return function(){
// This function returns the element of the array arr that corresponds to the I subscript each time it is executed
return arr[i++] || "Array traversal is complete"}}let next = increment(arr);
console.log(next()); //aa
console.log(next());//bb
console.log(next());//cc
console.log(next());// The array values are already iterated
Copy the code
8 First distinction (same argument, function will not be executed twice)
let fn = (function(){
let arr=[];// An array for caching
return function(val){
if(arr.indexOf(val)==-1) {// If the command is not in the cache, the command needs to be executed
arr.push(val);// Push the parameter into the cache array
console.log('Function executed',arr);
// Write the function you want to execute here
}else{
console.log('This function does not need to be executed.');
}
console.log('After the function is called, print it to see the cached array:',arr);
}
})();
fn(10);
fn(10);
fn(1000);
fn(200);
fn(1000);
Copy the code
The result is as follows:
You can obviously see that the first execution is saved and the second execution is direct fetch.
9 cache
For example, the sum operation, if there is no cache, each call will be repeated calculation, using the cache has been executed to find, directly returned, no need to recalculate
let fn = (function(){
let cache = {}
let calc = function (arr) {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum+=arr[i]
}
return sum;
}
return function() {
let args = Array.prototype.slice.call(arguments.0);
let key = args.join(', ')
let result , total = cache[key];
if(total){
console.log('Fetch from cache:',cache)// Print for easy viewing
result = total;
}else{
// recalculate, store in cache and assign to result
result = cache[key]=calc(args);
console.log('Store in cache:',cache)// Print for easy viewing
}
return result;
}
})();
fn(1.2.3.4.5);
fn(1.2.3.4.5);
fn(1.2.3.4.5.6);
fn(1.2.3.4.5.8);
fn(1.2.3.4.5.6);
Copy the code
The output