1. What is a closure
A closure is a function that has access to variables in the scope of another function. The most common way to create a closure is to create another function within a function. The created function can access the local variables of the current function.
Second, the characteristics of the closure
-
(1) Make it possible to access the internal variables of the function externally
-
(2) Variables will be resident in memory
-
(3) The use of global variables can be avoided to prevent global variable pollution;
3. The advantages and disadvantages of closure
-
Benefits: Variables inside other functions can be read and kept in memory all the time.
-
Disadvantages: May cause memory leaks or overflows.
4. Closures have two common uses
-
(1) The first use of closures is to enable us to access variables inside the function outside the function. By using closures, variables inside the function can be accessed externally by calling the closure function externally. This method can be used to create private variables.
-
(2) Another use of the closure is to keep the variable object in the function context that has already run in memory, because the closure function retains the reference of the variable object, so the variable object will not be recycled.
For example, AFunc
if there is a function inside function BFunc
, and function BFunc
can access AFunc
variables in function , then function BFunc
is a closure.
function AFunc() {
let aaa = 'aaa';
return function BFunc () {
console.log('闭包内console:', aaa);
}
}
AFunc()(); // '闭包内console:aaa'
In JS, the meaning of closure is to allow us to indirectly access the variables inside the function. Classic interview questions: the problem of defining functions es5
solved by using closures in loopsvar
for (var i = 1; i <= 10; i++) {
setTimeout(function loop() {
console.log(i)
}, i * 500); // 每500ms执行一次
}
First of all, because setTimeout
is an asynchronous function, all the loops will be executed first. At this time, i
is 11, so a bunch of 11 will be output. There are three solutions:
The first way is to use closures
for (var i = 1; i <= 10; i++) {
;
(function(j) {
setTimeout(function loop() {
console.log(j)
}, j * 500); // 每500ms执行一次
})(i)
}
The above is equivalent to
function func(i) {
// 此时的Loop形成了闭包
setTimeout(function loop() {
console.log(i)
}, i * 500); // 每500ms执行一次
}
for (var i = 1; i <= 10; i++) {
;
func(i); // 此时的i传入func作为func函数的参数,等同于他内部的变量
}
In the above code, the immediate execution function is first used to pass i into the function. At this time, the value is fixed on the parameter j and will not change. When the closure is executed next time, the variable j of the external function can be used loop
. , so as to achieve the purpose.
The second is to use setTimeout
the third parameter of the , which will be loop
passed in as a parameter of the function.
for (var i = 1; i <= 10; i++) {
setTimeout(
function loop(j) {
console.log(j)
},
i * 500,
i // 作为loop函数的参数传入,等同于内部自定义了变量,因此可以正确记录数字i的自增
)
}
The third way is to use let
define i to solve the problem, which is also the most recommended way
for (let i = 1; i <= 10; i++) {
setTimeout(function loop() {
console.log(i)
}, i * 500)
}
PS: let
How var
is it different from
You can also refer to: https://blog.csdn.net/qq_43145310/article/details/125737211
The biggest difference between let and var is that the scope of let declaration is block scope, while the scope of var declaration is function scope. let does not allow repeated declarations. Function scope > block scope.
Both var and let are used to declare variables, the difference is:
-
(1)
let
The declared variable cannot be declared repeatedly, butvar
can -
(2)
let
Declared variables cannot be variable promoted, butvar
can -
- When
var
declaring onevar变量
, the variable is hoisted to the top of the scope, however赋值的部分不会提升
.
- When
console.log(a);
var a = 'aaa';
-
- The a variable can be output before the statement declaring a, and the value is
undefined
, this is the variable promotion, andlet
the variable cannot be promoted when using the declared variable.
- The a variable can be output before the statement declaring a, and the value is
-
(3)
var
It is function scope andlet
block scope -
- If a variable is declared in a function
var
, the variable is valid throughout the function. For example, ifvar
a variable is declared in a for loop, it can also be used outside the for loop. Butlet
the scope is a block scope, which is only valid in the scope. For example,let
a variable declared in a for loop cannot be accessed outside the for loop.
- If a variable is declared in a function
-
(4) The variables declared in the global environment
let
do not belong to the top-level object (failed to verify successfully, to be confirmed) -
- The top-level object,
浏览器
referred to in the middlewindow
,node环境
refers toglobal
the object in the middle.
- The top-level object,
-
var
The declared variables belong to the top-level objectwindow
, so they can be accessed through the window. variable name, andlet
theconst
declared variables cannot be accessed in this way.
var name = 'Jerry';
console.log(window.name); // 'Jerry'
let age = 35;
console.log(window.age); // undefined
5. Points to note when using closures
-
(1) Because the closure will make the variables in the function be stored in the memory, the memory consumption is very large, so the closure cannot be abused, otherwise it will cause performance problems of the web page, and may cause memory leaks in IE. The solution is,
在退出函数之前,将不使用的局部变量全部删除
. -
(2)
闭包会在父函数外部,改变父函数内部变量的值
. So, if you use the parent function as对象(object)
a use, the closure as its public method (Public Method), and the internal variable as its private property (private value), then you must be careful not to change the parent function casually The value of the internal variable.