一、闭包的原理
在程序语言中,所谓闭包,是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外的执行域上的非持久型变量值能力的段落。这些外部执行域的非持久型变量神奇地保留他们在闭包最初定义(或创建)时的值。
白话: 我们可以用一个函数 去访问 另外一个函数的内部变量的方式就是闭包。
测试题
function outerFun()
{
var a=0;
function innerFun()
{
a++;
alert(a);
}
return innerFun; //注意这里 不加()
}
var obj=outerFun();//必须加()
obj(); obj();
var obj2=outerFun();
obj2(); obj2();
结果是 : 1 2 1 2
闭包的优点 :
优点:不产生全局变量,实现属性私有化。
缺点:闭包中的数据会常驻内存,在不用的时候要删掉否则会导致内存溢出。
二、闭包的函数传参
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>闭包的函数传参</title> 6 <style> 7 div{ 8 width: 100px; 9 height: 100px; 10 position: absolute; 11 left:0; 12 background-color: yellow; 13 } 14 </style> 15 </head> 16 <body> 17 <button id="btn1">右走</button> 18 <button id="btn2">左走</button> 19 <div id="box"></div> 20 </body> 21 </html> 22 <script> 23 /*//闭包原理 24 function outFun(){ 25 var num=10; 26 function inFun(){ 27 console.log(num); 28 } 29 return inFun;//返回函数体 不带括号 30 } 31 var obj=outFun();//调用函数 32 obj();//返回函数值*/ 33 34 //函数传参 35 /*function Fun(x){ 36 return function(y){ 37 console.log(x+y); 38 } 39 } 40 var obj=Fun(4);//把4传给x obj=function(){console.log(x)} 41 obj();// NaN 42 obj(2);//6*/ 43 44 45 var btn1=document.getElementById("btn1"); 46 var btn2=document.getElementById("btn2"); 47 var box=document.getElementById("box"); 48 49 function move(speed){ 50 return function(){ 51 box.style.left=box.offsetLeft+speed+"px"; 52 } 53 } 54 btn1.onclick=move(5); 55 btn2.onclick=move(-5); 56 </script>
三、实例
1、闭包版tab切换
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>闭包版tab栏切换</title> 6 <style> 7 *{ 8 margin: 0; 9 padding: 0; 10 } 11 .box{ 12 width: 405px; 13 height: 400px; 14 border:1px solid #c1c1c1; 15 margin: 100px auto; 16 /*overflow: hidden;*/ 17 } 18 .mt span{ 19 display: inline-block; 20 width: 80px; 21 height: 30px; 22 text-align: center; 23 line-height: 30px; 24 background-color: #ff4400; 25 border-right: 1px solid #c1c1c1; 26 cursor: pointer; 27 } 28 .mt .current{ 29 background-color: #3B90CD; 30 } 31 .mb li{ 32 width: 100%; 33 height: 370px; 34 background-color: #3B90CD; 35 list-style: none; 36 display: none; 37 } 38 .mb .show{ 39 display: block; 40 } 41 </style> 42 <script> 43 window.onload=function(){ 44 function tab(obj){ 45 //获取每个盒子的id 46 var target=document.getElementById(obj); 47 //获取对应id下的标签 48 var spans=target.getElementsByTagName("span"); 49 var lis=target.getElementsByTagName("li"); 50 for(var i=0;i<spans.length;i++) { 51 52 //function() {} ();立即执行函数 53 var timer=null; 54 spans[i].onmouseover = function (num) {//num 形参 55 return function () { 56 clearTimeout(timer); 57 timer = setTimeout(function () { 58 for (var j = 0; j < spans.length; j++) { 59 //清除所有的 类 60 spans[j].className = ""; 61 lis[j].className = ""; 62 } 63 //显示当前点击的类 64 spans[num].className = "current"; 65 lis[num].className = "show";//span和li对应起来 66 }, 300) 67 } 68 }(i);//i传参 69 spans[i].onmouseout=function(){ 70 clearTimeout(timer); 71 } 72 } 73 } 74 tab("one"); 75 tab("two"); 76 tab("three"); 77 } 78 </script> 79 </head> 80 <body> 81 <div class="box" id="one"> 82 <div class="mt"> 83 <span class="current">新闻</span><span>体育</span><span>娱乐</span><span>科技</span><span>视频</span> 84 </div> 85 <div class="mb"> 86 <ul> 87 <li class="show">新闻模块</li> 88 <li>体育模块</li> 89 <li>娱乐模块</li> 90 <li>科技模块</li> 91 <li>视频模块</li> 92 </ul> 93 </div> 94 </div> 95 96 <div class="box" id="two"> 97 <div class="mt"> 98 <span class="current">新闻</span><span>体育</span><span>娱乐</span><span>科技</span><span>视频</span> 99 </div> 100 <div class="mb"> 101 <ul> 102 <li class="show">新闻模块</li> 103 <li>体育模块</li> 104 <li>娱乐模块</li> 105 <li>科技模块</li> 106 <li>视频模块</li> 107 </ul> 108 </div> 109 </div> 110 111 <div class="box" id="three"> 112 <div class="mt"> 113 <span class="current">新闻</span><span>体育</span><span>娱乐</span><span>科技</span><span>视频</span> 114 </div> 115 <div class="mb"> 116 <ul> 117 <li class="show">新闻模块</li> 118 <li>体育模块</li> 119 <li>娱乐模块</li> 120 <li>科技模块</li> 121 <li>视频模块</li> 122 </ul> 123 </div> 124 </div> 125 </body> 126 </html>
2、闭包版屏幕缩放事件
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <div id="demo"></div> 9 </body> 10 </html> 11 <script> 12 var num=0; 13 var demo=document.getElementById("demo"); 14 window.onresize=throttle(function(){ 15 demo.innerHTML=window.innerWidth||document.documentElement.clientWidth; 16 num++; 17 console.log(num); 18 },300); 19 20 function throttle(fn,delay){//闭包 节流 21 var timer=null; 22 return function(){ 23 clearTimeout(timer); 24 timer=setTimeout(fn,delay);//delay控制延迟时间 25 } 26 } 27 28 </script>