1. The core of understanding and memory
A closure is a function that accesses the inner scope of another function
Closure causes: A reference to the upper scope is kept within the current function (typically by returning another function within the function)
2. Understanding and implementation of closures
First of all,
A closure is a function that accesses the inner scope of another function
What do we usually think about when we want to use variables inside a function outside of a function without knowing about closures?
1. Global variables!!
Change a local variable inside a function to a global variable, declare it in a global scope, and assign a value to a function so that the desired value can be fetched outside the function as long as the function has been called
// Global variables
var a;// Variables declared by let and const are at best part of script blocks and are not attached to the global window, so I'll change it to var
function fn(){
a=20;// Variable assignment
}
fn();// Function call
console.log(window.a);// get the result of the action inside the function
Copy the code
For the sake of image presentation, I still use the Node environment in the following images, but ensure that the results are the same as in the browserThere’s a better oneEach call is a +1 operation on the same global variable, which is cumulative
But!!!!! Most of the time, we don’t want to declare a global variable, because every time we call a, we call window.a. Doesn’t that feel like we’re using the window variable too much?
2. Don’t want to use global variables
If you use local variables directly from outside, the result is wrong! a is not defined
// Local variables
function fn(){
let a=30;
}
fn();
console.log(a);
Copy the code
So what should we do? Two ways of thinking about it,
Method 1: return a, throw a out of the function, let aa outside catch it!
Method 2: Expose an accessor (function) that others can access indirectly
2.1. Return local variables directly
Return a, throw a out of the function, and let aa outside catch it!
function fn(){
let a = 40;
return a;
}
let aa = fn();
console.log(aa);
Copy the code
Otherwise, I can play a and come back
2.2. Expose an accessor for external indirect access
function fn(){
let a=40;
// Get and set cannot be accessed by external objects
// Get is a global variable that is mounted to the global object
get = function(){
return a;
};
}
fn();
let aa = get();
console.log(aa);
console.log(window.get());
Copy the code
Again, you can play a and then go back
But what if I want to do this to A multiple times?
3. Perform multiple accumulative operations on the local variable
Both methods were also tested
3.1. Return directly
As can be seen from the result in the figure, because every time the function is executed, JS will perform garbage collection, the scope will be emptied and reclaimed, each time a is reassigned, so no matter how many times I call, I will only return the result of one call. How to solve the problem? You can get some inspiration from the global variable example in 1If we are in (parent) function there is a local variable, and (parent) function in another (child) functions to access the local variables, each time that we call (child) functions, because the (sub) function has a variable to its external references, can realize the local variable a cumulative changes, in order to in external (parent) function can operation, Returns the (child) function of the operation directly
And that, in turn, is our main closure, which is why closures typically behave like one function that returns another function
3.2. Expose an accessor for external indirect access
Why is that ok? This is a type of closure, because get and set also satisfy closures.Access the internal scope of other functionsSo, it is not necessary to return a function to generate a closure, but most of the time it does
Closure application scenarios
Timers, event listeners, Ajax requests, etc., all use closures. Examples of timers, such as anti-shock/throttling:
/ / image stabilization
const debounce = (fn,delayTime) = > {
let timerId, result
return function(. args) {
timerId && clearTimeout(timerId)
timerId = setTimeout(() = >result=fn.apply(this,args),delayTime)
return result
}
}
Copy the code
/ / throttling
const throttle = (fn, delayTime) = > {
let timerId
return function(. args) {
if(! timerId) { timerId =setTimeout(() = >{
timerId = null
return result = fn.apply(this,args)
},delayTime)
}
}
}
Copy the code
2, IIFE (immediately execute function), this kind of function is special, it has independent scope, does not pollute the global environment, but at the same time can prevent external access to internal variables, so many times will be used to do modular or simulate private methods for example:
var global = 'Global variable'
let Anonymous = (function() {
var local = 'Internal variable'
console.log(global) // Global variables}) ()console.log(Anonymous.local) // local is not defined======= split line ==============var global = 'Global variable'
let Anonymous = (function() {
var local = 'Internal variable'
console.log(global) // Global variables
return {
afterLocal: local
}
})()
console.log(Anonymous.afterLocal) // Internal variables
Copy the code
3. The timer
function counter2(){
let time = 0;
return function(){
time++;
console.log(time);
if(time>10) {clearInterval(timer); }}}let count = counter2();
count();
count();
count();
Copy the code
4. How do I view closures in a browser
function fn1(){
let a=11;
let b="bbb";
return function fn2(){
let c="c";
console.log(c);
console.log(a);
}
}
fn1()();
Copy the code
When running inside fn2, you create a Closure with only the external function variable a referenced inside
Four, to sum up
What is a closure?
A function that accesses the inner scope of another function
What causes closures?
A reference to the upper scope is kept within the current function
What are the advantages and disadvantages of closures?
Advantages:
- You can keep a variable in memory for a long time.
- Avoid contamination of global variables.
Disadvantages:
- Resident memory to increase memory usage.
- Improper use can easily cause memory leaks.
Five, the reference
Juejin. Cn/post / 696642…
zhuanlan.zhihu.com/p/22486908
Six, past wonderful
Prototype and prototype chain
This points to the