定义
《JavaScript高级程序设计》对闭包的定义:
闭包指那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。
e.g.:
function foo () {
a = 1
return function () {
console.log(a)
}
}
var bar = foo()
bar() // 1
思考
Q1:我们知道,当调用闭包的外部函数的时候,在函数执行结束之后,函数的执行上下文就会退出执行上下文栈,活动对象的也会被销毁。那为什么在外部函数被调用之后,再调用闭包的内部函数的时候还能够访问外部函数中的变量呢?例如,在上面例子中, var bar = foo() 执行结束之后,foo() 的变量对象已经被销毁了,为什么 bar() 执行的时候还能够访问到 foo() 中的变量 a 呢?
A1:这是因为作用域链的存在。回想一下一个函数从创建到执行的过程:
-
函数声明后,设置函数的 [[scope]] 内部属性,其中包含了该函数各级父级执行上下文的变量对象
-
函数被调用之后,创建一个执行上下文,并将这个执行上下文压入执行上下文栈中
-
复制函数的 [[scope]] 内部属性,创建作用域链
-
通过 arguments 创建活动对象并初始化
-
将活动对象添加到作用域链最前端
-
准备工作完成,执行函数
-
函数执行完毕,执行上下文出栈,销毁活动对象
从函数创建到执行的整个过程中,我们注意到&#