闭包:在程序语言中,所谓闭包,是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外的执行域上的非持久型变量值能力的段落。这些外部执行域的非持久型变量神奇地保留他们在闭包最初定义(或创建)时的值。
白话: 我们可以用一个函数 去访问 另外一个函数的内部变量的方式就是闭包。
(内部变量 是 局部变量 那我们知道,局部变量是不可以为别人随便使用也。)
function fun() { var num = 10; } console.log(num); // 这样子就错了 num 是一个局部变量
感受一下简单的闭包函数:
function outFun() { var num = 10; function inFun() { console.log(num); // 非常正常的写法 } return inFun; // 返回的是 inFun函数体 核心 } // 使用 console.log(outFun()); var demo = outFun(); // 看清楚 // outFun() 返回的是 function inFun() {console.log(num); } // 相当于 这句话 var demo = function inFun() {console.log(num); } demo(); // 其实,每个函数都算一个小闭包
function Fun(x) { return function(y) { console.log(x+y); } } var obj = Fun(4); // 相当于 obj = function() {console.log(x)} obj(); obj(2);
屏幕缩放事件(闭包版的函数节流)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <div id="demo"></div> </body> </html> <script> var num = 0; var demo = document.getElementById("demo") window.onresize = throttle(function(){ demo.innerHTML = window.innerWidth || document.documentElement.clientWidth; num++; console.log(num); },300); function throttle(fn,delay) { // 闭包 节流 var timer = null; return function() { clearTimeout(timer); timer = setTimeout(fn,delay); } } </script>
多个tab栏切换(闭包节流)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <style> * { margin: 0; padding: 0; } ul { list-style: none; } .box { 350px; height: 300px; border: 1px solid #ccc; margin: 100px auto; overflow: hidden; } .mt span { display: inline-block; 80px; height: 30px; background-color: pink; text-align: center; line-height: 30px; cursor: pointer; } .mt span.current { background-color: purple; } .mb li { 100%; height: 270px; background-color: purple; display: none; } .mb li.show { display: block; } </style> <script> window.onload = function() { //要想多个盒子不相互影响 ,我们可以通过id 给他们分开 //封装tab栏切换函数 // function tab(obj){ // var target = document.getElementById(obj); // var spans = target.getElementsByTagName("span"); // var lis = target.getElementsByTagName("li"); // for(var i=0;i<spans.length;i++) // { // // spans[i].index = i; // var timer = null; // spans[i].onmouseover = function (num) { // return function(){ // clearTimeout(timer); // timer = setTimeout(function(){ // for(var j=0; j<spans.length;j++) // { // spans[j].className = ""; // lis[j].className = ""; // } // spans[num].className = "current"; // lis[num].className = "show"; // },300) // } // }(i); // spans[i].onmouseout = function() { // clearTimeout(timer); // } // } // } // 上面注释的代码为节流的 function tab(obj) { var target = document.getElementById(obj); var spans = target.getElementsByTagName("span"); var lis = target.getElementsByTagName("li"); for (var i = 0; i < spans.length; i++) { // spans[i].index = i; var timer = null; spans[i].onmouseover = infun(i) function infun(num) { return function() { clearTimeout(timer); timer = setTimeout(function() { for (var j = 0; j < spans.length; j++) { spans[j].className = ""; lis[j].className = ""; } spans[num].className = "current"; lis[num].className = "show"; }, 300) } }(i); spans[i].onmouseout = function() { clearTimeout(timer); } } } tab("one"); tab("two"); tab("three"); } </script> </head> <body> <div class="box" id="one"> <div class="mt"> <span class="current">新闻</span> <span>体育</span> <span>娱乐</span> <span>八卦</span> </div> <div class="mb"> <ul> <li class="show">新闻模块</li> <li>体育模块</li> <li>娱乐模块</li> <li>八卦模块</li> </ul> </div> </div> <div class="box" id="two"> <div class="mt"> <span class="current">新闻</span> <span>体育</span> <span>娱乐</span> <span>八卦</span> </div> <div class="mb"> <ul> <li class="show">新闻模块</li> <li>体育模块</li> <li>娱乐模块</li> <li>八卦模块</li> </ul> </div> </div> <div class="box" id="three"> <div class="mt"> <span class="current">新闻</span> <span>体育</span> <span>娱乐</span> <span>八卦</span> </div> <div class="mb"> <ul> <li class="show">新闻模块</li> <li>体育模块</li> <li>娱乐模块</li> <li>八卦模块</li> </ul> </div> </div> </body> </html>