zoukankan      html  css  js  c++  java
  • 重新理解闭包

    闭包这个概念  自我几个月前开始学习JS开始  我就一直困惑

    之前也有所理解  但是后来长时间不用就给忘记了

    闭包:通俗的讲  大多数人所接受的就是 一个函数有权利使用另一个函数里的局部变量

    我看到了很多的不同之处

    用最简单的代码表示

    function out(){
    
    var age=21;
    
    function inner(){
      
      console.log(age);
    
    }
    
    return inner;
    
    }
    
    var fn=out();
     fn();  //22
    
    

    很符合概念 

    我觉得闭包就是在体现作用域

    inner 函数实在 out 函数里面定义地 

    所以console(age);

    就会变量搜索机制,首先在自己(inner)函数作用域里面找,没找到 就去out函数作用域里面找

    找到了  然后输出  如果在out里面没有找到的话  会再往更大的作用域找

    一直到window的作用域   下级作用域可以向上访问  上级作用域不能向下访问

    作用域就是指

    {  } 

    而且JS没有块级作用域

    for(var i=0;i<5;i++){

      console.log(i);// 1 2 3 4 5

    }

    cosole.log(i);//5

    i 不会因为出了 for 循环就被销毁了

    这点要注意

    好了  说了一点作用域方面的知识  现在回到了闭包

    闭包核心的就是return 看看代码 就知道了

    我的理解就是  return 返回的是inner的函数体   还有 inner所能访问的作用域!

    所以 inner 在哪里都可以访问到age 

    例子:

    function  test(){
                   var age=23;
                    var fn=out();
                     fn();  //21
                 
                 }
        
        test();//21

     它得到的是 21  而不是22  因为函数体和作用域一起返回了  那么最近的作用域不就是out函数作用域喽

     test 函数里面定义了age也不可能被覆盖滴  因为存在的作用域不同

     它返回了 作用域  所以它访问的都是那个作用域里面的变量 跟你的函数现在所在的作用域无关哦

     闭包其实是一种现象   就是所有人玩DNF都在刷图卖材料赚钱  这种现象叫搬砖

     总结一句话:跟你定义函数作用域有关,跟你执行函数的作用域无关

     与this相反  this 是与定义时无关,与执行时有关  比较记忆

     所以你如果不能很好的理解闭包

     那你就可以像我这样理解 就好了 

     返回的是函数本身+和函数所能访问的作用域

    举一个  大家常用的  

    闭包Tab栏切换

    <!doctype html>
    <html lang="en">
     <head>
      <meta charset="UTF-8">
      <meta name="Generator" content="EditPlus®">
      <meta name="Author" content="">
      <meta name="Keywords" content="">
      <meta name="Description" content="">
      <title>Document</title>
      <style type="text/css">
      *{margin:0;padding:0;}
       .box{
         140px;
         height:18px;
         position:relative;
         padding:6px 20px;
         margin:50px auto;
         background:#ff6666;
       }
    
       .box ul{
         list-style:none;
       } 
    
       .box li{
          18px;
          height:18px;
          background:#ff3300;
          line-height:18px;
          text-align:center;
          float:left;
          margin-right:5px;
          cursor:pointer;
       }
    
       .current{
         background:#ffccff!important;
       }
      </style>
     </head>
     <body>
    
      
      <div class="box">
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
        </ul>
      </div>
     
    <script type="text/javascript">
         function $(name){
              return document.querySelectorAll(name);
           }
    
            var  list=$(".box ul li");
            var len=list.length;
           for(var i=0;i<len;i++){
               list[i].onmouseover=(function(n){
                   
                   return function(){
                      for(var j=0;j<len;j++){
                    
                          list[j].className="";
                    
                      }
                    list[n].className="current";
                   
                   }
               })(i);
    
    
           }



    </script> </body> </html>

    for循环 每当执行list[i].onmouseover的时候   函数都会立即执行  传入当前的变量i 

    返回一个函数  这个就是形成了闭包呗  返回函数和函数能够访问到的作用域

    每当触发onmouseover的时候  都会执行 返回的那个函数

    然后执行代函数里面的for循环 把所有li的className 清空

    在执行list[n]  这句是最重要的  这里的n 就是定义onmouseover的时候传入的i 

    因为当定义的时候 函数立即执行 把 i 传递给了匿名函数 这个 i 就在 匿名函数的作用域里面了

    每个onmouseover都是保存着各自的 i

    所以当触发onmouseover的时候能够让li访问到之前保存在作用域中的 i

    也就实现了 点谁 谁背景颜色变化的需求

    我是这么理解的  我也是个菜鸟

    Over

  • 相关阅读:
    LAMP环境搭建博客
    PHP项目中经常用到的无限极分类函数
    在PHP项目中,每个类都要有对应的命名空间,为什么?
    一键解决docker pull hello-world的问题
    网盘10M速度下载-亿寻下载器
    《提问的智慧》
    idea出现 Error:(1, 1) java: 非法字符: 'ufeff'解决方式
    多线程的四种实现方式
    Java中的get()方法和set()方法
    Java构造器(构造方法/constructor)
  • 原文地址:https://www.cnblogs.com/liveoutfun/p/9328179.html
Copyright © 2011-2022 走看看