JavaScript函数进阶:闭包

news2025/1/23 3:57:56

变量作用域

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

1. 函数内部可以使用全局变量

2. 函数外部不可以使用局部变量。

3. 当函数执行完毕,本作用域内的局部变量会销毁

什么是闭包

闭包closure有权访问另一个函数作用域中变量函数。  -----  JavaScript 高级程序设计

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

<script>
 function fn1(){    // fn1 就是闭包函数
    var num = 10;
    function fn2(){
      console.log(num); // 10
    }
       fn2()
 }
  fn1();
</script>

被访问变量的是闭包

在 chrome 中调试闭包

1. 打开浏览器,按 F12 键启动 chrome 调试工具。

2. 设置断点。

3. 找到 Scope 选项(Scope 作用域的意思)。

4. 当我们重新刷新页面,会进入断点调试Scope 里面会有两个参数(global 全局作用域、local 局部作用域)。

5. 当执行fn2() 时,Scope 里面会多一个 Closure 参数 ,这就表明产生了闭包

闭包的作用

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

<script>
 function fn() {    
    var num = 10;    
    return function {      
         console.log(num); // 10             
     }
  }
  var f = fn();
  f()
</script>

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

闭包也是高阶函数

<!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>

闭包案例

1. 点击小li打印出当前小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>
    <style>
        ul li{
            cursor: pointer;
        }
    </style>
</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++){
            // 下面的点击事件是一个异步任务,而是点击了才执行,前面的是同步任务,会先执行,因此i已经变成了4
            lis[i].index=i
            lis[i].onclick=function(){
                console.log(this.index);
            }
        }
        // 2. 利用闭包的方式得到当前小li 的索引号
        for(var i=0;i<lis.length;i++){
            // 创建了四个立即执行函数 立即执行函数最后面的()的意思是执行,也可以传入一个参数
            // 立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数都可以使用它i的变量
            (function(i){
                // console.log(i);
                lis[i].onclick=function(){
                console.log(this.index);
            }
            })(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++){
            // 这个立即执行函数里面的i是用来接收的
            (function(i){
                setTimeout(function(){
                console.log(lis[i].innerHTML);
            },3000)
            })(i)
        }
    </script>
</body>

</html>

3. 计算打车价格

<!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>
        // 闭包应用-计算打车价格 
        // 打车起步价13(3公里内),  之后每多一公里增加 5块钱.  用户输入公里数就可以计算打车价格
        // 如果有拥堵情况,总价格多收取10块钱拥堵费
        // function fn() {};
        // fn();
       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
       console.log(car.price(1));//13
       console.log(car.yd(false));//13
    </script>
</body>

</html>

 因为立即执行函数,所以start和total都是闭包,可以在函数内部传,因此当console.log(car.yd(true));时原先的total还是23,它是在原有的基础上+10;而下面是覆盖操作

闭包总结

1.闭包是什么?   

闭包是一个函数 (一个作用域可以访问另外一个函数的局部变量

2. 闭包的作用是什么?

延伸变量的作用范围

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/40421.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Day13--商品列表-请求并渲染商品列表的数据

1.定义请求参数对象 接口部分&#xff1a; 文档部分&#xff1a; 我的操作&#xff1a; 1》在goods_list.vue中&#xff1a; 1>初步操作&#xff1a; 其效果图&#xff1a; 2>进一步操作&#xff1a; 在goods_list.vue中&#xff1a; 情况①&#xff1a; 情况②&…

python高级在线题目训练-第二套·主观题

1、《Walden》 是美国作家梭罗独居瓦尔登湖畔的记录,描绘了他两年多时间里的所见、所闻和所思。该书崇尚简朴生活&#xff0c;热爱大自然的风光&#xff0c;内容丰厚&#xff0c;意义深远&#xff0c;语言生动。 请用Python统计小说《Walden》 中各单词出现的频次&#xff0c;…

Metabase学习教程:视图-8

漏斗图 使用漏斗图显示步骤的进度。 图1。我们将用示例数据库构建一个漏斗图。 漏斗图用一系列台阶显示了指标。通常&#xff0c;它们用于显示有多少人通过特定的序列&#xff08;如网站上的结帐流程&#xff09;完成。第一步是多少人访问你的网站。然后有多少人浏览了一个产品…

【笔记】ABAQUS弹塑性分析

1. 弹塑性分析的主要问题 1.1 elastic-plastic deform behavior abaqus 默认的塑性表现行为是金属材料经典塑性理论&#xff0c;采用mises屈服面定义各向同性屈服。 一般金属材料都是各向同性材料&#xff0c;弹塑性行为&#xff1a; 小应变时&#xff0c;材料表现为线弹性&…

【5G MAC】随机接入流程中的 Msg2 (RAR)

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

FL Studio水果2023版本更新下载汉化教程

Image-Line宣布针对Win和Mac版本的数字音频工作站FL Studio的21版本更新。FL Studio2023是一个完整的软件音乐制作环境或数字音频工作站&#xff08;DAW&#xff09;。代表超过 23年的创新发展&#xff0c;它包含了您在一个包装中编排&#xff0c;编排&#xff0c;录制&#xf…

cocos creator实现浏览星球的功能,附源码

预览效果&#xff1a; 技术要点&#xff1a; 主摄像机的视场轴需要设置为水平。在场景下创建一个空节点用于挂载控制器脚本图片已进行各概念的说明 在“collisionNodeArray”属性下&#xff0c;放置需要点击的星球节点&#xff0c;系统会自己绑定碰撞器。 也可自己提前绑定。 布…

基于SSM的学籍证明打印系统设计与实现。

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

QT下TCP协议实现数据网络传输

QT开发框架以其跨平台的优势&#xff0c;在全世界IT界如雷贯耳。其封装了功能齐全的各种类&#xff0c;大大的提高了开发者的效率。本篇内容将介绍如何使用QT 6.4.1框架开发服务器和客户端程序&#xff0c;让两端能够首发消息&#xff0c;服务端往客户端发送文件&#xff08;客…

Spark在Yarn集群的两种提交模式

目录 一.Yarn Client(yarn的客户端模式) 二.Yarn Cluster(yarn的集群节点模式) 三.两者的差异 一.Yarn Client(yarn的客户端模式) 第一步&#xff1a;Driver端会在提交的本地机上运行 第二步&#xff1a;Driver端启动后会跟ResourceManager(RM)进行通信,申请启动一个Applic…

Linux安装Samba服务,基于Fedora

Linux安装Samba服务&#xff0c;基于Fedora1 安装samba服务2 启动samba服务3 更改配置信息4 使用windows系统进行连接5 其他说明1 安装samba服务 1 关闭防火墙及关闭防火墙开机自启 [whs02fedora ~]$ &#xff1a;sudo systemctl stop firewalld.service [whs02fedora ~]$ &a…

splay树:hdu4453 Looploop

题目链接如下&#xff1a; Problem - 4453 主要是要对区间操作和这种splay树的性质比较清楚。 关于区间我们设立两个额外节点&#xff0c;用来设立最开始的左右区间。 性质方面&#xff0c;其实就是二叉搜索树的性质&#xff0c;这里的体现就是中序遍历就是顺时针访问输入数…

《统计学习方法》 第十四章 聚类方法

聚类方法 1.聚类是针对给定的样本&#xff0c;依据它们属性的相似度或距离&#xff0c;将其归并到若干个“类”或“簇”的数据分析问题。一个类是样本的一个子集。直观上&#xff0c;相似的样本聚集在同类&#xff0c;不相似的样本分散在不同类。 2.距离或相似度度量在聚类中…

压力传感器

压力传感器 压力传感器是最常用的一种传感器&#xff0c;其应用范围有各种工业互通环境&#xff0c;涉及航空&#xff0c;航天&#xff0c;军工&#xff0c;石化&#xff0c;电力等。按照不同的测试&#xff0c;压力类型可分表压传感器&#xff0c;差压传感器&#xff0c;绝压…

现代密码学导论-19-基于伪随机函数的CPA安全

目录 3.5.2 基于伪随机函数的CPA安全 基于伪随机函数的加密示意图 CONSTRUCTION 3.28 构造基于伪随机函数的CPA安全的加密方案 THEOREM 3.29 方案3.28是CPA安全的 THEOREM 3.29 的证明 3.5.2 基于伪随机函数的CPA安全 基于伪随机函数的加密示意图 CONSTRUCTION 3.28 构造…

历史中的密码

角色 发送者、接收者和窃听者 当某个人向另一个人发送信息时&#xff0c;发出信息的人称为发送者&#xff0c;而收到信息的人称为接收者&#xff0c;被发送的信息有时也统称为消息&#xff08; message )。 窃听者 Eve 并不一定是人类&#xff0c;有可能是安装在通信设备上的某…

【JVM】jvm中的方法区简介

jvm中的方法区简介一、JVM体系结构二、方法区是什么&#xff1f;三、方法区能干什么&#xff1f;四、方法区总结一、JVM体系结构 二、方法区是什么&#xff1f; 本文所讲内容在上图中处于运行时数据区内的左侧部分&#xff0c;即 Method Area&#xff08;方法区&#xff09;&a…

REHL7.6静默安装Oracle19C

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&#x1f61…

【轨迹跟踪】基于matlab拓展卡尔曼滤波时序四旋翼无人机状态跟踪【含Matlab源码 2246期】

⛄一、拓展卡尔曼滤波时序四旋翼无人机状态跟踪 卡尔曼滤波算法为获得最优估计和最小误差方差&#xff0c;将从目标模型中得到的测量值一步步递推&#xff0c;实时获取新时刻的状态估计值。 假设目标状态方程和观测方程分别为&#xff1a; 其中&#xff0c;k为离散时间&…

投入产出公开数据集:世界投入产出表(1995-2014)、全国投入产出表(1990-2018)、分省市投入产出表(1997-2017)

一、数据介绍 数据名称&#xff1a;世界、全国、各省-投入产出表 数据年份&#xff1a;世界投入产出表(1995-2014)、全国投入产出表(1990-2018)、分省市投入产出表(1997-2017) 数据来源&#xff1a;WIOD、自计算 ① 世界投入产出表&#xff08;1995-2014&#xff09; downlo…