先理解:作用域、作用域链、函数作用域以及变量对象
.
.
给一段代码:
var global;
function a() {
var aa = 123
function b() {
aa = 111
console.log(aa)
}
// b()
return b
}
var res = a()
res()
本来fn a执行完后应该销毁,即作用域链断裂。但是它里面return了一个b,b的作用域链并未断裂,b在定义时,它的作用域链中是可以访问到fn a内的变量的。
此时的a函数调用和b函数生成是同一个作用域链
.
.
.
那么如何定义闭包?
闭包(Closure)可以精简凝练地定义为:一个函数以及创建该函数时所能访问的所有外部变量的组合。闭包允许一个函数访问并操作函数外部的变量,即使该函数在其外部作用域之外被调用。这种机制使得JavaScript等语言能够支持私有变量和模块化编程。
简单来说,闭包就是能够记住并访问其词法作用域(lexical scope)的函数,即使该函数在其词法作用域之外执行。
也就是说,能够读取其他函数内部变量的函数就是闭包
.
.
.
.
场景适用:
- 定时器传参
// 定时器传参
function a(aa) {
return function () {
console.log(aa)
}
}
setTimeout(() => {
const logFunc = a(123)
logFunc()
}, 1000)
闭包是一个函数值,它引用了其外部作用域中的变量。在这个例子中,a函数返回的匿名函数就形成了一个闭包,因为它引用了在a函数作用域中定义的aa变量。
.
要理解,尽管a函数的执行和logFunc变量的赋值都发生在setTimeout的回调函数中,但是闭包内的aa变量仍然能够保持其值(123),并且可以被闭包内部的代码访问。这是因为闭包记住了它被创建时的作用域环境。