函数实例非一般对象实例
函数只是一段静态的代码、脚本文本,因此它是一个代码书写时,以及编译期的、静态的概念;
而闭包则是函数的代码在运行过程中的一个动态环境,是一个运行期的 、动态的概念。
由于引擎对每个函数建立其独立的上下文环境,因此当函数被再次执行或进入函数体内的代码时,就将会得到闭包内的全部信息。
闭包具有两个特点:
第一是闭包作为与函数成对的数据,在函数执行过程中处于激活(即可访问)状态;
第二是闭包在函数运行结束后,保持运行过程的最终数据状态。
因此函数的闭包总的来说决定了两件事:
闭包所对应的函数代码如何访问数据,以及闭包内的数据何时销毁。
对于前者来说,涉及作用域(可见性)的问题;
对于后者来说,涉及数据引用的识别。
闭包包括的是函数运行实例的引用、环境(environment,用来查找全局变量的表)、
以及一个由所有upvalue引用组成的数组,每个闭包可以保有自己的upvalue值。
闭包对应于运行期的函数实例的,而不是对应函数(代码块)的。
由于闭包对应于函数实例,那么我们只需要分析哪些情况下产生实例,就可以清楚地知道运行的闭包环境。
不同函数实例,访问不同闭包的upvalue
C++中一个函数调用结束后,除了静态变量,局部变量没有意义了。
而js中,一个函数也是对象,函数调用结束后在某些情况下其局部变量仍然有效。
通过对象实例的访问函数this.getProp,访问局部变量 var p。
在函数中将内部函数作为返回值。内部函数可以访问外部函数的变量。
局部变量其实是“调用对象(call object)”的属性