一、闭包
1.1、说明
        变量根据作用域的不同分为两种:全局变量和局部变量。
- 函数内部可以使用全局变量。
- 函数外部不可以使用局部变量。
- 当函数执行完毕,本作用域内的局部变量会销毁。
1.2、什么是闭包
| 12
 3
 4
 5
 
 | # 闭包(closure)指有权访问另一个函数作用域中变量的函数,闭包是一个函数。指的是可以访问另一个函数作用域中变量的函数。
 
 # 简单理解就是
 一个作用域可以访问另外一个函数内部的局部变量。
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | <body><script>
 
 function fn1() {
 var num = 10;
 
 function fn2() {
 console.log(num);
 };
 
 fn2();
 }
 fn1();
 
 
 </script>
 </body>
 
 | 

1.3、闭包的作用
1.3.1、问题引入
    我们怎么能在 fn() 函数外面访问 fn() 中的局部变量 num 呢 ?例如:
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | <body><script>
 function fn1() {
 var num = 10;
 }
 
 
 </script>
 </body>
 
 | 
1.3.2、实现
        我们可以返回一个函数,在这个函数中去访问num的数据。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 
 | <body><script>
 function fn1() {
 var num = 10;
 
 return function() {
 console.log(num);
 }
 }
 
 
 var func = fn1();
 
 
 func();
 
 
 
 var func = function() {
 console.log(num);
 }
 
 func();
 
 
 </script>
 </body>
 
 | 
1.4、闭包案例
1.4.1、案例1
        点击li输出索引号。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | <body><ul>
 <li>赵敏</li>
 <li>张无忌</li>
 <li>周芷若</li>
 <li>金毛狮王</li>
 </ul>
 <script>
 
 
 
 
 var liObjs = document.querySelector("ul").querySelectorAll("li");
 
 for (var i = 0; i < liObjs.length; i++) {
 
 
 liObjs[i].index = i;
 liObjs[i].onclick = function() {
 console.log(this.index);
 }
 }
 </script>
 </body>
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | <body><ul>
 <li>赵敏</li>
 <li>张无忌</li>
 <li>周芷若</li>
 <li>金毛狮王</li>
 </ul>
 <script>
 
 
 
 
 var liObjs = document.querySelector("ul").querySelectorAll("li");
 
 for (var i = 0; i < liObjs.length; i++) {
 
 
 (function(i) {
 liObjs[i].onclick = function() {
 console.log(i);
 }
 })(i);
 }
 </script>
 </body>
 
 | 
1.4.2、案例2
        定时器中的闭包。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | <body><ul>
 <li>赵敏</li>
 <li>张无忌</li>
 <li>周芷若</li>
 <li>金毛狮王</li>
 </ul>
 <script>
 
 
 
 var liObjs = document.querySelector("ul").querySelectorAll("li");
 
 for (var i = 0; i < liObjs.length; i++) {
 
 
 (function(i) {
 setTimeout(function() {
 console.log(liObjs[i].innerHTML);
 }, 3000)
 })(i);
 }
 </script>
 </body>
 
 | 
1.4.3、案例3
        计算打车价格。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | <body><script>
 
 
 
 
 
 
 var car = (function() {
 var start = 13;
 var total = 0;
 return {
 
 price: function(n) {
 if (n <= 3) {
 total = start;
 } else {
 total = start + (n - 3) * 5
 }
 return total;
 },
 
 yd: function(flag) {
 return flag ? total + 10 : total;
 }
 }
 })();
 console.log(car.price(5));
 console.log(car.yd(true));
 </script>
 </body>
 
 |