闭包
-
变量作用域
- 变量作用域的不同分为两种:全局变量和局部变量
- 函数内部可以使用全局变量
- 函数外部不可以使用局部变量
- 当函数执行完毕,本作用域内的局部变量会销毁
-
什么是闭包
-
闭包(closure)指有权访问另一个函数作用域中变量的函数。
-
使用变量所在的函数为闭包函数
-
简单理解就是:一个作用域可以访问另外一个函数内部的局部变量
//闭包:fun这个函数作用域 访问了另外一个函数fn 里面的局部变量num function fn() { var num = 10; function fun() { console.log(num); } fun(); } fn(); //输出10 -
在fn外面的作用域可以访问fn内部的局部变量
function fn() { var num = 10; function fun() { console.log(num); } return fun; } var f = fn(); f(); //外面f的作用域调用了fn内部的num局部变量,因为将fun返回给了f,fn为闭包 -
闭包是典型的高阶函数
-
闭包的主要作用:延申了变量的作用范围
-
-
闭包案例
-
循环注册点击事件(利用闭包立即执行函数传入i,这样立即执行函数里面的函数就都能使用i)
<ul class="nav"> <li>榴莲</li> <li>臭豆腐</li> <li>鲱鱼罐头</li> <li>大猪蹄子</li> </ul> <script> //闭包应用-点击li输出当前li的索引号 //可以利用动态添加属性的方式 var lis = document.querySelector('.nav').querySelectorAll('li'); for(var i =0 ;i < lis.length;i++) { lis[i].onclick = function() { console.log(i); //因为点击事件是异步任务,for是同步任务,所以当点击时for循环已经完成,此时点击输出为4 } } //利用闭包的方式得到li的索引号 for(var i =0;i < lis.length;i++) { //利用for创建了4个立即执行函数 (function(i) { // console.log(i); lis[i].onclick = function() { console.log(i); //此时onclick的function函数使用了外部立即执行函数的i,产生了闭包,即立即执行函数为闭包 } })(i); //后面的括号表示执行函数,在执行时传入实参i(当前循环的i),所以前面的function需要有i作为形参 } </script> -
循环中的setTimeout()
<ul class="nav"> <li>榴莲</li> <li>臭豆腐</li> <li>鲱鱼罐头</li> <li>大猪蹄子</li> </ul> <script> //闭包应用:在3秒钟之后,打印所有li元素的内容 var lis = document.querySelector('.nav').querySelectorAll('li'); for(var i = 0;i < lis.length; i++) { (function(i) { setTimeout(function() { console.log(lis[i].innerHTML); //因为setTiomout的function也是异步任务,所以需要利用闭包传入当前的i,执行同步任务for循环将四个异步计时器推入执行栈,再同时调用异步回调定时器函数(延迟函数的回调) },3000) })(i); } </script> -
计算打车价格
<script> //闭包应用-计算打车价格 //打车起步价13(3公里内),之后每多加一公里增加5块钱。用户输入公里数就可以计算打车价格 //如果有拥堵情况,总价格多收取10块钱拥堵费 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 falg ? total + 10 :total } } })(); console.log( car.price(5)); //23 console.log(car.yd(true)); //33 console.log( car.price(1)); //13 console.log(car.yd(false)); //13 </script>
-
-
闭包总结
-
闭包是什么?
- 闭包是一个函数(一个作用域可以访问另外一个函数的局部变量)
-