要了解闭包产生的原因,先要理解词法作用域和函数是JavaScript的第一公民。
词法作用域
词法作用域第一次听可能会觉得这是一个神秘的东西。其实概念很浅显,在词法分析阶段生成的作用域,词法分析阶段,就可以理解为写代码阶段,当你把函数写在某个位置上时,它的作用域就已经确定了,对应的还有动态作用域,与本文无关,这里我就不介绍啦,有兴趣的可以查查资料。
函数是JavaScript的第一公民
JavaScript的函数也是对象,可以有属性,可以赋值给一个变量,可以放在数组里作为元素,可以作为其他对象的属性,可以作为函数的参数,可以作为函数的返回值,什么都可以做,别的对象能做的它能做,别的对象不能做的它也能做。这就是第一公民。
而闭包就是词法作用域和函数是JavaScript的第一公民这二种机制相互作用而产生的现象
举个例子
const a = 1
function test() {
const a = 2;
return function () { //写在这个位置上时,它的作用域就已经确定
console.log(a)
}
}
const fun = test()
fun() //打印出 2
上面test函数执行时会返回一个新的函数并赋给fun, 这就是函数是JavaScript的第一公民的能力,可以作为函数的返回值,可以赋值给一个变量,当fun执行时,根据词法作用域,不会打印全局的a,而是神奇的打印了test函数内部的a, 这就是词法作用域和函数是JavaScript的第一公民这二种机制相互作用产生的自然现象,并不是什么高深的技巧。