了解闭包
理解闭包闭包是JavaScript的高级功能,要想深入了解JavaScript就必须要吃透闭包。看下面的代码: function f1
理解闭包
闭包是JavaScript的高级功能,要想深入了解JavaScript就必须要吃透闭包。
看下面的代码:
function f1(){ var f1_i = 0;return function f2(){return ++f1_i;} }var f3 = f1();alert(f3());//1alert(f3());//2
上面的代码中的函数f2就是闭包。
闭包的概念:闭包”是一个表达式(一般是函数),它具有自由变量以及绑定这些变量的环境 。 这句话很不好理解,结合这个例子,所谓的自由变量就是f1_i,它被f2绑定了。
大家从运行的结果可以看出来函数f1的变量f1_i的值是在累加的,这就说明函数f1的内存空间没有释放,其实就相当于全局变量了,这就是闭包的一个应用;在JavaScript
中我们一直不希望有很多的全局变量,用闭包就可以解决这个问题,它不但使局部变量想全局变量那样常驻内存,而且外部不能随便修改这个变量(全局变量就谁都能修改了)。
好的,那么为什么函数f1的内存空间没有释放呢,这是因为f2是f1“活动对象”的属性,f3就是返回的f2,也就是仍然调用了f1的引用,所以f1不会被垃圾回收。
下面我们看JavaScript创建一个函数的过程:
1,创建“活动对象”,并创建它的属性对象arguments(这是一个类似数组结构的对象,保存了调用函数时传递的参数)。
2,将形参作为“活动对象”的属性,如果调用函数时传递的参数与形式参数一致,则将相应参数的值赋给这些命名属性(否则,会给命名属性赋 undefined 值)。
3,定义的内部函数(f2)会以其声明时所用名称为可变对象创建同名属性。
4,在函数内部声明的所有局部变量创建为可变对象的命名属性。
5, this 关键字的赋值。如果所赋的值引用一个对象,那么前缀以 this 关键字的属性访问器就是引用该对象的属性。如果所赋(内部)值是 null,那么 this 关键字则引用全局对象。