js闭包
在运行 JavaScript 代码时,它的运行环境是非常重要的,运行环境可能是如下几种中的一种:
全局代码——首次执行代码的默认环境。
函数代码——每当执行流程进入函数体时。
function createCounter() {
let counter = 0
const myFunction = function() {
counter = counter + 1
return counter
}
return myFunction
}
const increment = createCounter()
const c1 = increment()
const c2 = increment()
const c3 = increment()
console.log('example increment', c1, c2, c3)
现在让我们来看看这段代码将如何执行:
第 1-8 行,我们在全局执行上下文中创建了一个新变量 createCounter,它包含了一个函数定义。
第 9 行,我们在全局执行上下文中声明了一个名为 increment 的新变量。
第 9 行,我们调用 createCounter 函数并将其返回值赋给 increment 变量。
第 1-8 行,调用函数,创建新的本地执行上下文。
第 2 行,在本地执行上下文中,声明一个名为 counter 的新变量,并赋值为 0。
第 3-6 行,在本地执行上下文中声明名为 myFunction 的新变量。变量的内容是另一个函数定义,也就是第 4 行和第 5 行。
第 7 行,返回 myFunction 变量的内容。删除本地执行上下文,myFunction 和 counter 不再存在,控制权返回到调用上下文。
第 9 行,在调用上下文(全局执行上下文)中,createCounter 返回的值被赋给了 increment。变量 increment 现在包含了一个函数定义,也就是 createCounter 返回的函数定义。它不再被标记为 myFunction,但定义没有变化。在全局上下文中,它被标记为 increment。
第 10 行,声明一个新变量(c1)。
继续第 10 行,查找变量 increment,它是一个函数,然后调用它。它包含了之前返回的函数定义,也就是第 4-5 行所定义的内容。
创建新的执行上下文,没有参数,开始执行这个函数。
第 4 行,counter = counter + 1,在本地执行上下文中查找变量 counter。我们只是创建了上下文,并没有声明任何局部变量。在全局执行上下文中,没有标记为 counter 的变量。Javascript 将会执行 counter = undefined + 1,声明一个标记为 counter 的新局部变量,并为其指定数值 1,因为 undefined 其实被视为 0。
第 5 行,我们返回 counter 的值,也就是数值 1。我们销毁本地执行上下文和变量 conter。
第 10 行,返回值(1)被分配给 c1。
第 11 行,我们重复步骤 10-14,c2 也被赋值为 1。
第 12 行,我们重复步骤 10-14,c3 也被赋值为 1。
第 13 行,我们记录变量 c1、c2 和 c3 的值。
js闭包的作用是让局部变量可以在全局内使用。