zoukankan      html  css  js  c++  java
  • 闭包——之初理解

    闭包,是javascript中的一个概念,对于初学者很难理解抽象的概念,看了很多大牛们的解释,也是似懂非懂的,今天在知乎上看到很多“大神”们对“闭包”做了又一番解释,在其中也学到了不少,下面就来说下自己对闭包的理解吧。 

    闭——外面的变量看不到里面的,包——可以对内部变量操作,返回一个'包';

    闭包并不是私有的,闭的意思不是封闭“内部状态”,而是封闭“外部状态” ;
    用知乎上“大神”更简洁的一句话总结:闭包就是一个有记忆的函数;
    在《js高级程序设计》里面的解释:闭包是指有权访问另一个函数作用域中的变量函数。

    1.看一个简单的闭包的例子:
    function A(){
        function B(){
           console.log("Hello world!");
        }
        return B;
    }
    var c = A();
    c();//Hello world!

    最常见的闭包,就是在一个函数内部再创建一个函数;也是最简单的闭包,有了上面简单的概念认识,我们分析一下闭包函数和普通函数有什么不同的地方:

    上面代码翻译成自然语言如下:

    (1)定义了一个普通函数A

    (2)在A中定义了普通函数B

    (3)在A中返回B(确切的讲,在A中返回B的引用)

    (4)执行A(),把A的返回结果赋值给变量 c

    (5)执行 c()

    把这5步操作总结成一句扯淡的话就是:

    函数A的内部函数B被函数A外的一个变量 c 引用

    把这句扯淡的话再加工一下就变成了闭包的定义:

    当一个内部函数被其外部函数之外的变量引用时,就形成了一个闭包。 

    2.demo是理解抽象东西的最好方法,下面来看一下闭包怎么用,又会在哪些地方能用到它呢。

    (1.)改变字体的大小(点击不同的字体,改变body字体的大小)

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="UTF-8">
            <title></title>
            <script>
                window.onload = function() {
                             function ftsize(sizes){
                             return function(){
                                   document.body.style.fontSize=sizes+"px";
                                } 
                          }
                          var fontsize12=ftsize(12); 
                          var fontsize14=ftsize(14); 
                          var fontsize16=ftsize(22); 
                          document.getElementById("font-size12").onclick=fontsize12;
                          document.getElementById("font-size14").onclick=fontsize14;
                          document.getElementById("font-size22").onclick=fontsize22; 
                }
            </script>
        </head>
    
        <body>
            <a href="#" id="font-size12">12号字体</a>
            <a href="#" id="font-size14">14号字体</a>
            <a href="#" id="font-size22">22号字体</a> 
        </body> 
    </html>
    View Code

    (2.)用户小调查,当文本框获取焦点时提示用户输入正确的内容 

    <!DOCTYPE html>
    <html> 
        <head>
            <meta charset="UTF-8">
            <title></title>
            <script>
                window.onload = function() { 
                    function showHelp(help) {
                        document.getElementById('help').innerHTML = help;
                    } 
                    function makeHelpCallback(help) {
                        return function() {
                            showHelp(help);
                        };
                    } 
                    function setupHelp() {
                        var helpText = [
                            {'id': 'email','help': '填写你正确的email地址'},
                            {'id': 'name', 'help': '填写你的真实姓名'    }, 
                            {'id': 'age', 'help': '你的年龄必须大于16岁'}
                        ];
                        for (var i = 0; i < helpText.length; i++) {
                            var item = helpText[i];
                            document.getElementById(item.id).onfocus =
                                makeHelpCallback(item.help);
                        }
                    }
                    setupHelp();
                }
            </script>
        </head> 
        <body>         
            <p id="help">用户小调查</p>
            <p>邮箱: <input type="text" id="email" name="email"></p>
            <p>姓名: <input type="text" id="name" name="name"></p>
            <p>年龄: <input type="text" id="age" name="age"></p>
        </body> 
    </html>
    View Code

    (3.)点击不同的li时弹出对应的index  

            我们可以想到的一种方法就是用JQ循环每一个li获取下标代码如下:        

    <!DOCTYPE html>
    <html> 
        <head>
            <meta charset="UTF-8">
            <title></title>
            <script src="js/jquery.js"></script>
            <script> 
                $(function() {
                    $("li").each(function() {
                        $(this).click(function() {
                            alert($(this).index());
                        })
                    })
                })
            </script>
        </head> 
        <body>
            <ul>
                <li>aaaaaa</li>
                <li>bbbbbb</li>
                <li>ccccccc</li>
                <li>dddddd</li>
            </ul>
        </body> 
    </html>

     我们不用JQ,用JS来实现呢代码如下:

     <script>
        window.onload = function() {
             var nodes = document.getElementsByTagName("li");
             for (i = 0; i < nodes.length; i += 1) {
                       nodes[i].onclick = function() {
                       alert(i); //值全是4
                    };
                 }
          }
    </script>  

     值全为4,这是为什么呢,当事件(li被点击)被执行时,外层函数的for循环早已结束,所以索引i已经变成4,因此我们点击后会返回里层函数变量对象指向的值i也就是4;解决这个问题我们这时又可以用到闭包了

    代码如下: 

    function alertindex(nodes) {
             var helper = function(a) {
                     return function() {
                            alert(a);
                        };
                 };
                 var i = 0;
                 for (i = 0; i < nodes.length; i++) {
                        nodes[i].onclick = h elper(i);
                  }
              };
             alertindex(document.getElementsByTagName("li"));
    }

    i是alertindex中的一个变量,它的值在helper中被引用,当for循环一次函数helper就被调用执行一次,i的值就在原来的基础上累加1。因此,alertindex中的i一直保存在内存中。即得到我们想要的结果。 

    这就是闭包的作用,有时候我们需要一个模块中定义一个变量:希望这个变量一直保存在内存中但又不会“污染”全局的变量,这个时候,我们就可以用闭包来定义这个模块。 

    总结

    有了简单的理解和应用之后,在以后的更多的实践应用中会对闭包有越来越多越深的理解。

    参考:http://www.codeceo.com/article/javascript-closures.html(让你分分钟学会 JavaScript 闭包

            https://www.zhihu.com/question/31383111(怎么更好的理解闭包)

            https://www.zhihu.com/question/28849447(到底该如何理解闭包)

            https://www.zhihu.com/question/19554716(JavaScript 里的闭包是什么?应用场景有哪些?)

  • 相关阅读:
    js正則表達式语法
    购买DigtalOcean VPS 以及 连接Linux
    UVA 246
    牵一发动全身【Nhibernate基本映射】
    jquery.validate+jquery.form提交的三种方式
    [Python] 发送email的几种方式
    递归算法浅谈
    最小二乘法多项式曲线拟合原理与实现
    王立平-Android中对图像进行Base64编码
    [置顶] EasyMock的简单使用
  • 原文地址:https://www.cnblogs.com/hfxm/p/5556530.html
Copyright © 2011-2022 走看看