理解闭包,首先必须理解变量作用域。前面提到,JavaScript 有两种作用域:全局作用域和函数作用域。函数内部可以直接读取全局变量。但是,函数外部无法读取函数内部声明的变量。
闭包就相当于一些变量+函数块,直接理解就是函数中再定义的函数。
注意: 在js中函数可以改变函数外部变量的值, 而python不行!
function f1() {
let n = 999
function f2() {
console.log(n)
}
return f2
}
let result = f1()
result() // 999
上面代码中,函数f1的返回值就是函数f2,由于f2可以读取f1的内部变量,所以就可以在外部获得f1的内部变量了。
闭包就是函数f2,即能够读取其他函数内部变量的函数。由于在 JavaScript 语言中,只有函数内部的子函数才能读取内部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。闭包最大的特点,就是它可以“记住”诞生的环境,比如f2记住了它诞生的环境f1,所以从f2可以得到f1的内部变量。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
eg2:
function startAt(x){
function inc(y){
return x + y
}
return inc
}
可以简写成:
function startAt(x){
return function inc(y){
return x + y
}
}
let a = startAt(1) //function
console.log("func", a) //[Function: inc]
console.log("res", a(1)) //2
/*
let a = startAt(1) 相当于:
let a = function inc(y){
let x = 1
return x + y
}
*/