1. Concept
Closures are functions that can read variables inside other functions. For example, in javascript, only sub-functions inside the function can read local variables, so closures can be understood as "A function defined inside a function". In essence, a closure is a bridge that connects the inside of the function with the outside of the function.
Two, characteristics
-
function nested function
-
Parameters and variables outside the function can be referenced inside the function
-
Parameters and variables are not garbage collected
3. Usage
1. Function as return value
function closure(num) {
var count = num
// t()使用
// return function getCount() {
// return count++
// }
return {
plus: function() {
return count++
},
minus: function() {
return count--
},
getCount: function() {
return count
}
}
}
var t = closure(0)
console.log('初始值:' + t.getCount())
t.plus()
console.log('plus后:' + t.getCount())
t.minus()
console.log('minus后:' + t.getCount())
(1) Classic example - timer and closure
1.1 Realize sequential input of 0 1 2 3 4
for (var i = 0; i < 5; i++) {
// var则输出5个5,改成let按顺序输出0-4
setTimeout(() => {
console.log(Date.now() + ' ' + i)
}, 100)
}
1.2 Introduce a closure to save the variable j, put setTimeout into the immediate execution function, pass the loop value j in the for loop as a parameter, and print out 0 1 2 3 4 at the same time after 100 milliseconds
for (var j = 0; j < 5; j++) {
(function(j) {
setTimeout(() => {
console.log(Date.now() + ' ' + j)
}, 100)
})(j)
}
1.3 So if we want to output numbers sequentially every 100 milliseconds, how should we change it?
for (var k = 0; k < 5; k++) {
(function(k) {
setTimeout(function() {
console.log(Date.now() + ' ' + k)
}, 100 * k)
})(k)
}
k*100 is to set different times for the four timers and start them at the same time, but the execution time is different. The interval of each timer is 100 milliseconds, which realizes the effect of printing every 100 milliseconds.
2. Closures are passed as parameters
// 第一种写法
function fun2() {
var num = 24
console.log(++num)
}
function fun1(fun) {
fun()
}
fun1(fun2)
// 输出结果
// 25
// 第二种写法(匿名函数回调)
void (function(fun) {
fun()
})(fun2)
// 输出结果
// 25
Summarize:
advantage:
- Can access local variables inside the function
- Can avoid global variable pollution
- The values of these variables are always kept in memory and will not be automatically cleared after the outer function is called.
shortcoming:
- It will increase memory usage, and abuse of closures will affect performance and lead to problems such as memory leaks.