专栏首页前端知识分享第66天:闭包的原理和函数传参

第66天:闭包的原理和函数传参

一、闭包的原理

在程序语言中,所谓闭包,是指语法域位于某个特定的区域,具有持续参照(读写)位于该区域内自身范围之外执行域上的非持久型变量值能力的段落。这些外部执行域的非持久型变量神奇地保留他们在闭包最初定义(或创建)时的值

白话: 我们可以用一个函数 去访问 另外一个函数的内部变量的方式就是闭包

测试题

 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>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 第31天:动态生成节点-京东轮播图创建

    一、获取节点属性 getAttribute()通过这个方法可以得到某些元素的某些属性 alert(demo.getAttribute("class"));

    半指温柔乐
  • 第28天:js-Tab栏切换封装函数

    二、变量和属性 var index=10;//变量 var arr=[];//数组 arr.index=20;//index为自定义属性,只能在arr下使用 a...

    半指温柔乐
  • 第27天:js-表单获取焦点和数组声明遍历

    1、this指事件的调用者 2、input.value 表单更换内容 3、innerHTML更换盒子里的内容,文字、标签都能换。 4、isNaN("12")如果...

    半指温柔乐
  • 第28天:js-Tab栏切换封装函数

    二、变量和属性 var index=10;//变量 var arr=[];//数组 arr.index=20;//index为自定义属性,只能在arr下使用 a...

    半指温柔乐
  • 前端的CRUD增删改查的小例子

    Dream城堡
  • 仿百度地图上拉下滑抽屉盒

    王小婷
  • 我在移动web开发中遇到的各种问题

    目前(2015年8月3日15:02:24)在大部分安卓手机都发现这个问题,触发bug的条件知道了,但是原因未知。触发bug的条件是需要横向滚动的层不能位于纵向滚...

    黒之染
  • css3 - 纯css实现一个轮播图

    以上gif,只用到了5张图片,一个html+css,没有任何js。然后实现了自动轮播效果。

    xing.org1^
  • 看了180分钟的视频,写了半天的代码

    清晨,日常打开B站,被首页此视频的标题所吸引,虽一看就是标题党,但还是没能抑制住好奇心。 视频共计60*3分钟,学习到了很多东西。其中后半部分有许多正三观的见...

    易墨
  • 第4天:JS入门-给div设置宽高背景色

    今天学习了js入门课程,听的不多,做了个小练习,给div设置宽高、背景色。一点点都是进步。核心代码如下:

    半指温柔乐

扫码关注云+社区

领取腾讯云代金券