248 闭包:概念,作用,案例,思考题案例,chrome 中调试闭包

5.1 变量的作用域复习

变量根据作用域的不同分为两种:全局变量和局部变量。

  1. 函数内部可以使用全局变量。
  2. 函数外部不可以使用局部变量。
  3. 当函数执行完毕,本作用域内的局部变量会销毁。

5.2 什么是闭包

闭包(closure):指有权访问另一个函数作用域中的变量的函数。

简单理解就是 ,一个作用域可以访问另外一个函数内部的局部变量。

【被访问的局部变量所在的函数,就是闭包函数】

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 闭包(closure)指有权访问另一个函数作用域中变量的函数。
        // 闭包: 我们fun 这个函数作用域 访问了另外一个函数 fn 里面的局部变量 num
        // 被访问的局部变量所在的函数,就是闭包函数
        function fn() {
            var num = 10;

            function fun() {
                console.log(num);
            }
            fun();
        }
        fn();
    </script>
</body>

</html>

5.3 在 chrome 中调试闭包

  1. 打开浏览器,按 F12 键启动 chrome 调试工具。
  2. 设置断点。
  3. 找到 Scope 选项(Scope 作用域的意思)。
  4. 当我们重新刷新页面,会进入断点调试,Scope 里面会有两个参数(global 全局作用域、local 局部作用域)。
  5. 当执行到 fn2() 时,Scope 里面会多一个 Closure 参数 ,这就表明产生了闭包。

5.4 闭包的作用

提问:我们怎么能在 fn() 函数外面访问 fn() 中的局部变量 num 呢 ?

作用:延伸变量的作用范围。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 闭包(closure)指有权访问另一个函数作用域中变量的函数。
        // 一个作用域可以访问另外一个函数的局部变量
        // 我们fn 外面的作用域可以访问fn 内部的局部变量
        // 闭包的主要作用: 延伸了变量的作用范围
        function fn() {
            var num = 10;
            // function fun() {
            //     console.log(num);
            // }
            // return fun;

            return function() {
                console.log(num);
            }
        }
        var f = fn();
        f();
        // 类似于
        // var f = function() {
        //         console.log(num);
        //     }

        // var f =  function fun() {
        //         console.log(num);
        //     }
    </script>
</body>

</html>

5.5 闭包的案例

1、利用闭包的方式得到当前li 的索引号

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <ul class="nav">
        <li>榴莲</li>
        <li>臭豆腐</li>
        <li>鲱鱼罐头</li>
        <li>大猪蹄子</li>
    </ul>
    <script>
        // 闭包应用-点击li输出当前li的索引号
        // 1. 我们可以利用动态添加属性的方式
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            lis[i].index = i;
            lis[i].onclick = function() {
                // console.log(i);
                console.log(this.index);

            }
        }
        // 2. 利用闭包的方式得到当前小li 的索引号
        for (var i = 0; i < lis.length; i++) {
            // 利用for循环创建了4个立即执行函数
            // 立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数都可以使用它的i这变量
            (function(i) {
                // console.log(i);
                lis[i].onclick = function() {
                    console.log(i);

                }
            })(i);
        }
    </script>
</body>

</html>


2、闭包应用-3秒钟之后, 打印所有li元素的内容

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <ul class="nav">
        <li>榴莲</li>
        <li>臭豆腐</li>
        <li>鲱鱼罐头</li>
        <li>大猪蹄子</li>
    </ul>
    <script>
        // 闭包应用-3秒钟之后,打印所有li元素的内容
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            console.log(i);
            // 先创建好 4 个 同步任务的立即执行函数,3秒后,再执行 这 4 个 同步任务的立即执行函数
            (function(i) {
                // console.log(i);
                setTimeout(function() {
                    console.log(lis[i].innerHTML);
                }, 3000)
            })(i);
        }
    </script>
</body>

</html>


3、闭包应用-计算打车价格

/*需求分析
打车起步价13(3公里内),  之后每多一公里增加 5块钱.  用户输入公里数就可以计算打车价格
如果有拥堵情况,总价格多收取10块钱拥堵费*/

 var car = (function() {
     var start = 13; // 起步价  局部变量
     var total = 0; // 总价  局部变量
     return {
       // 正常的总价
       price: function(n) {
         if (n <= 3) {
           total = start;
         } else {
           total = start + (n - 3) * 5
         }
         return total;
       },
       // 拥堵之后的费用
       yd: function(flag) {
         return flag ? total + 10 : total;
       }
    }
 })();
console.log(car.price(5)); // 23
console.log(car.yd(true)); // 33

5.6 思考题案例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 思考题 1:
        var name = "The Window";
        var object = {
            name: "My Object",
            getNameFunc: function() {
                return function() {
                    return this.name;
                };
            }
        };

        console.log(object.getNameFunc()()); // The Window
        // var f = object.getNameFunc();
        // // 类似于
        // var f = function() {
        //     return this.name;
        // }
        // f();

        // 思考题 2:
        var name = "The Window";  
        var object = {    
            name: "My Object",
            getNameFunc: function() {
                var that = this;
                return function() {
                    return that.name;
                };
            }
        };
        console.log(object.getNameFunc()()); // My Object
    </script>
</body>

</html>

原文地址:https://www.cnblogs.com/jianjie/p/12231550.html

时间: 2024-08-01 03:30:11

248 闭包:概念,作用,案例,思考题案例,chrome 中调试闭包的相关文章

在 Chrome 中调试 Android 浏览器

最近需要使用 Chrome Developer Tools 调试 Android 浏览器,但是官方指南并不是很好使,经过一番折腾,终于调试成功了,在此把经验分享给需要的朋友. Chrome Developer Tools 是前端工程师必不可少的工具,它极大的提高了我们的开发调试效率.在移动开发的时代,我们也必须掌握手机浏览器在 Chrome 中调试的方法.本篇仅介绍 Android. 环境 不同的环境可能存在一些差异,我的环境是: Windows 10 电脑 Chrome 50.0.2661.7

在Chrome 中调试Javascript

在前面的两篇文章中我们讲了如何在IE中调试Javascript和在Visual Studio中调试Javascript,在本篇内容中,我们讲一下如何在谷歌 Chrome中调试Javascript. Chrome 是Google 提供的一款非常优秀的浏览器,内置了开发者工具,可以方便我们对JS代码进行调试.有了使用IE来调试Javascript的经验,在使用Chrome进行调试的时候会变得很方便. 使用Chrome打开我们要调试的页面,然后使用快捷键F12打开开发者工具,当然,你也可以在工具菜单中

Chrome 中调试Javascript

使用Chrome打开我们要调试的页面,然后使用快捷键F12打开开发者工具,当然,你也可以在工具菜单中找到.Chrome开发者工具如图: Elements选项卡是对界面上的元素进行选择的,我们要进行调试的代码在Sources 选项卡中. 打开Sources选项卡,点击左侧的小箭头打开所有资源,选择我们的页面: 我们要调试这个页面的代码,所以就打开这个页面,然后点击行号可以添加断点: 点击界面中的按钮,我们能够捕获到刚添加的断点: 添加监视的方法和在IE中的方法是一样的:选中变量,在变量上面单击,选

在桌面chrome中调试android设备中的web页面

准备工作 1, 桌面版chrome 2, Android设备(安装有chrome浏览器) 3, Android-sdk Android-sdk安装及设置 SKD安装 从http://developer.android.com/sdk/index.html下载android-sdk开发包,安装后,执行SDK Manager.exe,安装android SDK Platform-tools工具包. 环境变量配置: 在环境变量添加path,并添加路径<sdk>/platform-tools; 添加后

如何在sublime+chrome中调试php代码?

1.搭建php本地运行环境具体点击如何使用phpstudy本地搭建多站点(每个站点对应不同的端口) 2.下载php_xdebug.dll, [5.3版以上的php下载地址]http://pecl.php.net/package/xdebug [5.3版及其以下的php下载地址]http://pecl.php.net/package/xdebug/2.2.7/windows 注意版本要对应,不然可能会不能用.   3.安装php xdebug扩展(即在配置php.ini文件加入以下代码) [XDe

javascript中的闭包解析

学习javaScript已经有一段时间了,在这段时间里,已经感受到了JavaScript的种种魅力,这是一门神奇的语言,同时也是一门正在逐步完善的语言,相信在大家的逐步修改中,这门语言会逐步的完善下去,在上一篇随笔中,和大家分享了JavaScript中独有的类中的继承方式,今天呢,就跟大家分享一下我这几天一直在搞,却还是搞的不是很透彻的闭包问题,对于一个初学者而言,JavaScript中的闭包无疑是一个难点,而且也是我们必须要掌握的一个重点,那么今天我就跟大家分享一下我在学习闭包的时候的感悟以及

理解C#中的闭包

闭包的概念 内层的函数可以引用包含在它外层的函数的变量,即使外层函数的执行已经终止.但该变量提供的值并非变量创建时的值,而是在父函数范围内的最终值. 闭包的优点 使用闭包,我们可以轻松的访问外层函数定义的变量,这在匿名方法中普遍使用.比如有如下场景,在winform应用程序中,我们希望做这么一个效果,当用户关闭窗体时,给用户一个提示框.我们将添加如下代码: private void Form1_Load(object sender, EventArgs e) { string tipWords

在Chrome+Visual Studio中调试asp.net程序很慢的问题(Firefox也有类似问题)

在Chrome+Visual Studio中调试asp.net程序很慢的问题(Firefox也有类似问题) 今天开始起在Chrome中调试,发现问题主要出在菜单栏(layout文件)中,google了一番,查到很多原因,不过最终解决方法倒是很简单,特此分享一下: 在C:/Windows/System32/drivers/etc里边有一个hosts文件,用记事本打开,里边最后几行原来是: # localhost name resolution is handled within DNS itsel

从闭包案例中学习闭包的作用,会不会由你。

在文章初识js中的闭包中讲解了闭包的一些概念,但是对于初学者来说可能并不是特别的容易理解,我今天用两个案例来解释闭包可能会好理解一些,在讲案例之前,我们需要了解一些闭包的概念.在看这篇文章之前,请先看上面的那篇文章,不然效果不会太好. 闭包的理解: 所谓的闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互不干扰. 闭包的创建: 一个函数中嵌套另外一个函数,并且将这个函数return出去,然后将这个return出来的函数保存到了一个变量中,那么就创建了一个闭包. 为啥要学闭包之没有使