借用高程(JavaScript高级程序设计)中对闭包的定义:闭包是指有权访问另一个函数作用域中的变量的函数。而我想对这句话加一个修饰条件就更能反应闭包的含义了。
闭包是指在任何地方都有权访问另一个函数作用域中的变量的函数。所以,通常我们会在一个函数里return另一个函数,这样更能体现 在任何地方,有权访问另一个函数(外层函数)中的变量。下面我们可以通过一张图来更加直观的理解下,闭包函数为何能在任何地方都有权访问外层函数内部的变量。
我们都知道,控制变量的访问权限这是作用域链的职责(),从上图中,我们可以看出,闭包函数 bibao 的内部属性 [[Scopes]] 上记录了定义当前函数时的作用域链,当执行bibao函数时,会将[[Scopes]]属性取出生成一个作用域链并且将当前函数的活动对象推入作用域链的最顶层,这样,不管在什么位置就都能访问内部函数的属性,如图中的 k 变量。
⚠️注意,当内部函数没有指向或者引用内部函数中的变量时,这个时候,内部函数是不会构成闭包的,请参考下图。
如上图所示,闭包函数内部属性 [[Scopes]] 中没有外层函数的活动对象,所以执行该函数时无法访问外层函数的变量 k。因此,当内层函数中没有引用外层函数中的变量时,就不会构成一个闭包函数。