JavaScript的闭包详解

Posted 奔跑的蜗牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript的闭包详解相关的知识,希望对你有一定的参考价值。

(1)定义:
  函数内部返回一个函数,返回出来的这个函数叫做被我们称之为闭包(个人理解的最简单的表现形式,)
(2)为什么要使用闭包呢?

局部变量在函数执行完之后就会被GC回收,有时候我们想在外部访问内部的变量,这个时候就用到了闭包

(3)闭包有两个作用:

a.访问函数内部的变量(函数作为返回值)
b.保存作用域(函数作为参数传递)

 1   //1.访问函数内部的变量(函数作为返回值)
 2     function test(){
 3         var age = 18;
 4         return function(){
 5             console.log(age);
 6         }
 7     }
 8 
 9     var myTest = test();
10     console.log(myTest);//为匿名函数,function(){console.log(age)}
11     myTest();//18
12 
13 
14 
15     //另一个例子
16     function fn() {
17         var max = 10;
18         return function bar(x) {
19             if (x > max) {
20                 console.log(x);
21             }
22         }
23     }
24     var f1 = fn();
25     console.log(f1);//function bar(x){if(x>max){console.log(x);}}
26     f1(15);//结果为15
27 
28 
29     //保存作用域(函数作为参数传递)
30 
31     //保存作用域
32     function test(){
33         var a = 1;//局部变量
34         hehe = function(){//全局变量
35             a++;
36         };
37         return function(){
38             console.log(a);
39         }
40     }
41 
42     var haha = test();//此时haha为test()执行完之后的返回值,匿名函数function(){consolloe.log(a)}
43     haha();//打印1
44     hehe();//hehe函数为全局变量,可以在外边执行,此处a++
45     haha();//打印2
46     hehe();//同上
47 
48     //注意:haha为全局变量,不会被GC回收,所以test函数的返回值,一直存在,test的作用域一直存在,不会被GC回收
49 
50     //注意:自由变量跨域取值时,要去创建这个函数的作用域取值,而不是“父作用域”;
51     //
52     var max = 10;
53     var fn = function(x){
54         if(x>max){
55             console.log(max);//10
56             console.log(x);//15
57         }
58     };
59 
60     (function(f){
61         var max = 100;
62         f(15);
63     })(fn);

 


(4)闭包的使用
假设页面上有5个div节点,我们通过循环来给每个div绑定onclick事件,按照索引顺序,点击第一个div时弹出0,点击第2个div时弹出1,以此类推。
1  <body>
2     <div>1</div>
3     <div>2</div>
4     <div>3</div>
5     <div>4</div>
6     <div>5</div>
7 </body>
 1 //闭包的使用
 2 
 3     var nodes = document.getElementsByTagName(‘div‘);
 4     for(var i=0;i<nodes.length;i++){
 5         nodes[i].onclick = function(){
 6             console.log(i);
 7         }
 8     }
 9     //思考一下,存在什么问题??
10     // 点击每一个打印的都是5是不是···
11 
12 
13     var nodes = document.getElementsByTagName(‘div‘);
14     for(var i=0;i<nodes.length;i++){
15         (function(i){ //块级作用域或私有作用域
16             nodes[i].onclick = function(){
17                 console.log(i);
18             }
19         })(i)
20     }
21     //上述方法优点:把每次循环的i值都封闭起来

 


(5)使用闭包的注意点

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,
所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
 

以上是关于JavaScript的闭包详解的主要内容,如果未能解决你的问题,请参考以下文章

javascript中的闭包closure详解

JavaScript 闭包详解

JavaScript闭包和回调详解

详解JavaScript闭包

JavaScript中的闭包详解

JavaScript之作用域与闭包详解