位置: 编程技术 - 正文

JavaScript闭包详解(js闭包详解)

编辑:rootadmin

推荐整理分享JavaScript闭包详解(js闭包详解),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:javascript闭包概念,javascript闭包详解,javascript闭包详解,javascript闭包运行原理,javascript闭包原理,javascript闭包原理,javascript闭包的作用,javascript 闭包,内容如对您有帮助,希望把文章链接给更多的朋友!

在上一篇文章我们对预解释作了概述,在写这篇博文前打算写几个经典案例,考虑到那些案例综合性比较强,也就循序渐进的有了这篇博文,这样对于学习和深入JavaScript也更加容易入手。

一同事去面试,面试官问了一道题:你写一个闭包我看下?于是同事火速写出如下代码:

然后面试官摇摇头说道:“这怎么能叫闭包呢?”,最终两人争执不下,同事果断走人,面试官什么玩意儿?(本故事纯属虚构,如有雷同纯属巧合)

闭包可能在很多人眼中都是“高大不好上”的技术,可能在很多人眼中只有这样才算得上闭包:

示例1:

示例1 PS:这个看起来不怎么高级,看样子这人水平不咋地哦!

示例2:

示例2 PS:这个看起来比上一个要高级,而且第一个括号前还加了一个分号,为何加一个分号,好吧我们先把这个疑问留这儿,后面会讲到。

示例3:

示例3 PS:这个最高级了,简直吊炸天,我读书少,你们别骗我!

撸主读书不多,仅能写出这三种“闭包”,相信博友们能写出更多更优秀的“闭包”;到此请先暂停我的瞎掰,接下来研究下函数运行的机制,貌似有人已经知道了,肯定是作用域,我真的很不想在标题上再加上这个作用域,这样总感觉差点儿意思,这个几个东西本来都是一起的,为何要重复呢?老习惯,先上代码:

好简单的说,我们画图(撸主只会用Windows自带的画图软件,若有更好的请博友推荐)来分析下:

分析1

从图中我们看到了两个作用域,一个是window作用域(顶级作用域),一个是fn调用的时候形成的一个私有作用域;那什么是作用域,作用域其实就是代码执行的环境。举个栗子,一个学生他的学习环境是学校,相当于他的作用域是学校,假如这个学生很调皮,晚上经常FanQiang去网吧打游戏,相当于形成了一个私有环境,这个作用域就是网吧。好吧!这个栗子太TM像撸主本人了,不由感叹一句:“少壮不努力,长大干挨踢”。还是回到正题,其实函数fn的定义就是指向一段代码的描述(图中红框),当这个fn调用(图中的绿框)的时候,就会形成一个作用域,当然这个作用域中的代码执行前也会预解释,我是不会告诉你这个作用域是当它执行完毕后会被销毁,这个fn再次调用也会形成一个新的作用域,然后执行前预解释,然后代码执行,最后执行完毕销毁。

理解闭包

我们知道函数被调用在执行的时候会形成一个私有作用域(执行环境),这个私有作用域就是闭包。回头再看看闭包还是传说中的“高大不好上”吗?我们再回头看看第一个面试故事,还有我写的三个示例,它们其实都是闭包,确切的说那三个示例都是闭包的常用形式。

应用场景

JavaScript闭包详解(js闭包详解)

现在有这样一个需求:HTML页面中有一个ul标签,ul下面有5个li标签,要求任意点击一个li,弹出被点击的这个li所在的索引(索引从0开始)位置,HTML结构如下:

机智的我火速写出如下代码:

最终测试,看是否完美实现这个需求:

发现无论点击多少次,最终都弹出这个结果,而需求期望的结果是:点击列表1弹出0,点击列表2弹出1,点击列表3弹出2……此时此刻只想用这幅图来形容现在的心情:

(当原型在演示时没能按设计的要求运行时的样子)

这可如何才好,为何总是弹出5呢?理论上很正确呀!我们不妨画图来分析下:

其实我们只是给每一个li的onclick其实就是保存的一段函数的描述字符串,这个字符串内容就是上图红框中的内容,如果您还是不信,我有图有真相:

在Chrome控制台下输入:lis[4].onclick,其值就是函数的描述。当我们在点击第5个列表时,其实就是相当于lis[4].onclick(),调用了这段函数描述,我们知道函数在被调用执行的时会形成一个私有作用域,在这个私有作用域下也是先预解释,然后代码执行,此时会去找i,在当前私有作用域下没有i,然后去window作用域下找到了i,因此每次点击都弹出5。

显然上面的代码无法满足这个需求,我们代码那么写是不正确的,我们思考一下出现问题的原因是什么?其实原因就是每次点击的时候都是读取的window下的i,此时这个i的值已经是5了,于是有了如下代码:

方式一:

方式二:

方式三:

一口气写了三种方式,其思想都是一样的,就是将这个变量i用一个私有变量存储起来,这里我就只讲方式二,当然明白其中一个其余也就都明白了。按照惯例,我们画图来一步步分析下:

我详细的对整个代码执行做了描述,需要注意的是:每个li的onclick属性都要占用(function(i){ … })(i)作用域,当这个函数执行完毕后不会被销毁,因为它被外面的li(这个li是window作用域下的)占用着,因此这个作用域不会被销毁。当点击任意一个li时,function(){ alert(i); }会被执行,也会形成一个作用域,这个作用域没有i,它会去(function(){ … })(i)作用域找i,最终在形参找到i,这个形参i的值就是for循环时传进去的;这个例子巧妙地使用闭包来贮存值,完美解决问题。

PS:刚刚说(function(i){ … })(i)为什么在前面加一个分号,其原因就是防止前面的语句忘记加分号,这样导致JavaScript在解析时出错,仅此而已。当然上面的一个应用场景就是Tabs实现原理,可以有其他实现方式,比如自定义属性方式、通过DOM节点关系找到索引,而撸主采用这样一种方式只是为了加深对闭包的理解。

总结

闭包并不是传说中的高大不好上,其核心就是理解函数定义、调用,函数调用时会形成一个新的私有作用域,当某个作用域被外面占用,那么这个作用域将不会被销毁。撸主读书甚少,有说得不对的地方请博友们指正,同时也感谢大家对撸主文章的支持。

JavaScript中原型和原型链详解 javascript中的每个对象都有一个内置的属性prototype,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。意思是是prototype属性保存着对另一

javascript操作符"!~"详解 快过年放假了,也终于闲下来了。每天游览于各种技术文章中,这种状态好极了。下午看篇关于js的文章,其中有如下这么一段引起了我的注意。(function

javascript中var的重要性分析 本文实例分析了javascript中var的重要性。分享给大家供大家参考。具体分析如下:javascript的var作用是声明变量。一般情况下不写都不会出错,但有些情况

标签: js闭包详解

本文链接地址:https://www.jiuchutong.com/biancheng/383899.html 转载请保留说明!

上一篇:浅谈javascript的调试(javascript的主要内容)

下一篇:JavaScript中原型和原型链详解(js原型使用场景)

  • 公司的股东就是公司的发起人
  • 金税四期的到来意味着什么
  • 外币实收资本入账汇率
  • 被投资方宣告发放股票股利
  • 为企业担保
  • 库存现金日记账格式
  • 权益性投资收益的账务处理
  • 申报抵扣了不做账怎么处理?
  • 发票冲红增值税怎么申报
  • 查定征收方式适用于什么
  • 年终结账后,应当更换新账的有( )
  • 税后工资反推税前工资计算方法
  • 小规模纳税人出租房屋增值税税率是多少
  • 物业代收自来水水费
  • 定期定额个体工商户个人所得税
  • 开具的增值税专用发票上注明的价款为50万元
  • 服务业的营业成本怎么算
  • 采用支票结算方式的基本业务处理程序
  • 购买固定资产如何记账
  • 暂估冲红的分录怎么写
  • 如何从Windows 10注销其他用户
  • 提供给生产工人的住房的租赁费用应计入
  • 企业收缩案例
  • 小米手环2支持nfc功能?
  • iphone操作系统
  • kb4586863更新
  • 承兑开出去能收回吗
  • 土地出让金的收费标准 60%
  • 内部审计范围有哪些
  • 新手刚接触财务
  • PHP:json_last_error_msg()的用法_JSON函数
  • 企业购入设备涉及的税种
  • 购买加油卡如何开发票
  • PHP+Mysql+Ajax实现淘宝客服或阿里旺旺聊天功能(前台页面)
  • 民营医院所得税税率
  • 收到社保稳岗补贴转入营业外收入要交企业所得税吧
  • vue框架搭建步骤
  • 固定资产的特征有哪些
  • php会员系统
  • 不合格机器设备怎么处理
  • sqlserver2008安装完在哪打开
  • 资产类备抵科目借方表示
  • 个体户怎么计算养老金
  • mysql 优化技巧
  • 盈余公积提取是什么意思
  • 结算备付金会计分录
  • 销售退货和销售换货的区别
  • 购车买的保险分别是什么
  • 单位买的职工社保自己可以去社保局领卡吗
  • 公司做的形象墙效果图
  • 高新技术企业一定是先进制造业吗
  • 二次加工型的企业有哪些
  • 会计明细账怎么记
  • 现金日记账怎么划线
  • 剩余股利政策发放股利后的年末未分配利润
  • 内部交易固定资产折旧为什么调整
  • sqlserver数据库事物日志已满
  • windows 9x
  • vista电脑密码忘了怎么解除
  • centos crond
  • win10预览版和正式版区别
  • Win10系统照片应该打不开
  • mac 硬盘数据恢复
  • linux 操作系统
  • 怎么更改windows商店的安装位置
  • win8右边栏设置
  • win7怎么删除wifi已连接过的网络
  • win7没有nvidia控制面板怎么调节亮度
  • 微软发布ChatGPT功能
  • Cocos2dx3.2 Crazy Tetris 游戏输入(键盘事件,重力事件,触摸屏事件)
  • 批处理命令是什么语言
  • unity ui批处理
  • js 修改 css
  • HorizontalListView
  • javascript怎么学
  • 发票查询结果打印怎么弄
  • 契税完税证明怎么补打
  • 山东统一发票查询平台
  • 年度营业账簿印章怎么写
  • 一般纳税人企业是什么意思
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设