JavaScript 小记 之 闭包(Closures)

Closures are functions that refer to independent (free) variables.html

闭包是以静态方式/词法方式进行存储全部父做用域的一个函数sublime-text

在JavaScript高级程序设计里面经过一个 createComparisonFunction() 函数和这个函数的做用域链之间的关系图说得很明白为何闭包能够访问外部函数的变量, 是由于闭包的做用域链不只包括本身本地的活动对象, 还包括外部函数做用域链所指向的活动对象.数组

在JavaScript高级程序设计, JavaScript精粹 都有一个相似的例子 在循环里建立闭包.闭包

(为了测试, 作了一点点修改)函数

 1 var fn = function() {
 2     var result = [];
 3     for(var i = 0; i < 3; i++) {
 4         result[i] = function() {
 5             console.log(i);    
 6         };
 7     }
 8     return result; 
 9 };  
10 
11 var list = fn();
12 list[0]();   //3
13 list[1]();   //3
14 list[2]();   //3
 1 var fn = function() {
 2     var result = [];
 3     for(var i = 0; i < 3; i++) {
 4         result[i] = (function(num) {
 5             return function() {
 6                 console.log(num);
 7             };
 8         })(i);
 9     }
10     return result; 
11 };  
12  
13 var list = fn();
14 list[0]();   //0
15 list[1]();   //1
16 list[2]();   //2

当时为了让本身能够了解得更完全 本身也把做用域链画了出来 但愿对部分同窗有用oop

第一个函数做用域关系图:测试

从第一个函数的做用域关系图能够看出 之因此数组里的每一个函数都打印3是由于每一个函数在各自本地的活动对象里都找不到 i 因此继续往上找 在外部函数的活动对象里找到了i 可是此时的i 在循环结束后值为3 因此每一个函数打印均为3spa

第二个函数做用域关系图:设计

第二个函数把一个当即执行的函数赋给了result数组, 并传入了i 因此此时result[x]的活动对象里就多一个变量num 值为 i (函数参数按值传递) 因此返回的函数打印num时 根据做用域链找到了result[x] 活动对象里的num 并打印出 num的值3d

 

经过画这两个函数的做用域链关系图, 就能够清楚地弄懂闭包的工做原理, 也就不会对闭包那么惧怕啦! 

PS. 上面两个例子在JSLint 里都是会报错的: Don’t make functions within a loop

因此你们在实际的程序当中就不要这样使用 能够在循环外变量定义函数后再在循环里使用

最后附上 sublime-text 3 怎么安装SublimeLinter 的教程 http://www.sublimelinter.com/en/latest/installation.html

 

若有错误 欢迎指正 : ) 

相关文章
相关标签/搜索