位置: 编程技术 - 正文

js学习之----深入理解闭包(深入浅出javascript)

编辑:rootadmin

推荐整理分享js学习之----深入理解闭包(深入浅出javascript),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:深入浅出node js,深入理解javascript pdf,javascript深入理解,深入javascript,深入javascript,javascript深入理解,深入javascript高级语法,深入理解javascript特性.pdf,内容如对您有帮助,希望把文章链接给更多的朋友!

闭包算是js里面比较不容易理解的点,尤其是对于没有编程基础的人来说。

其实闭包要注意的就那么几条,如果你都明白了那么征服它并不是什么难事儿。下面就让我们来谈一谈闭包的一些基本原理。

闭包的概念

一个闭包就是一个函数和被创建的函数中的作用域对象的组合。(作用域对象下面会说)

通俗一点的就是 “ 只要一个函数中嵌套了一个或多个函数,那么我们就可以称它们构成了闭包。 ”

类似这样:

闭包的原理

1、外部函数的局部变量若会被闭包函数调用就不会在外部函数执行完毕之后立即被回收。

我们知道,不管什么语言,操作系统都会存在一个垃圾回收机制,将多余分配的空间回收掉以便减小内存。而一个函数的生命周期的是从调用它开始的,在函数调用完毕的时候函数内部的局部变量等都会被回收机制回收。

我们拿上述例子来说,当我们的外部函数A调用完毕时,A中的局部变量i按理说就会被操作系统回收而不存在,但是当我们用了闭包结果就不是那样了,i并不会被回收。试想,如果i被回收了那么返回的函数里面岂不是就是打印undefined了?

i为什么没有被回收?

在javascript执行一个函数的时候都会创建一个作用域对象,将函数中的局部变量(函数的形参也是局部变量)保存进去,伴随着那些传入函数的变量一起被初始化。

所以当调用A的时候就创建了一个作用域对象,我们姑且称之为Aa,那么这个Aa应该是这样的: Aa { i: 5; }; 在A函数返回一个函数之后,A执行完毕。Aa对象本应该被回收,但是由于返回的函数使用了Aa的属性i,所以返回的函数保存了一个指向Aa的引用,所以Aa不会被回收。

所以理解作用域对象,就能理解为什么函数的局部变量在遇到闭包的时候不会在函数调用完毕时立即被回收了。

再来个例子:

js学习之----深入理解闭包(深入浅出javascript)

你能说出的它的作用域对象Ww是什么吗?

Ww{ age: ; name: 'wind'; };

2、每调用一次外部函数就产生一个新的闭包,以前的闭包依旧存在且互不影响。

3、同一个闭包会保留上一次的状态,当它被再次调用时会在上一次的基础上进行。

每调用一次外部函数产生的作用域对象都不一样,你可以这样想,上面的例子,你每次传入的参数age不一样,所以就每次生成的对象不一样。

每调用一次外部函数那么就会生成一个新的作用域对象。

这个代码让我们发现了两个事情,一、当我们连续调用两次a();,num会在原基础上自加。说明同一个闭包会保留上一次的状态,当它被再次调用时会在上一次的基础上进行。 二、我们的b();的结果为,说明它是一个新的闭包,并且不受其他闭包的影响。

我们可以这样想,就好比我们吹肥皂泡一样,我每次吹一下(调用外部函数),就会产生一个新的肥皂泡(闭包),多个肥皂泡可以同时存在且两个肥皂泡之间不会相互影响。

4、在外部函数中存在的多个函数 “ 同生共死 ”

以下三个函数被同时声明并且都可以对作用域对象的属性(局部变量)进行访问与操作。

由于函数不能有多个返回值,所以我用了全局变量。我们再次可以看出在我们第二次调用A()时产生了一个新的闭包。

当闭包遇到循环变量

当我们说到闭包就不得不说当闭包遇到循环变量这一种情况,看如下代码:

怎么会这样呢?我们预想的三个输出应该是 item0 1, item1 2, item2 3。为什么结果却是返回的result数组里面存储了三个 item2 undefined ?

原来当闭包遇到循环变量时都是循环结束之后统一保存变量值,拿我们上面的例子来说,i是循环变量,当循环全部结束的时候i正好是i++之后的3,而arr[3]是没有值的,所以为undefined,有人会疑惑:为什么item的值是item2,难道不应该是item3吗?注意,在最后一次循环的时候也就是i = 2的时候,item的值为item2,当i++,i = 3循环条件不满足循环结束,此时的item的值已经定下来了,所以此时的arr[i]为arr[3],而item为item2。这样能理解吗?如果我们将代码改成这样那就说得通了:

那么问题来了,如何改正呢?且看代码:

我们可以用一个自执行函数将i绑定,这样i的每一个状态都会被存储,答案就和我们预期的一样了。

所以以后在使用闭包的时候遇到循环变量我们要习惯性的想到用自执行函数来绑定它。

标签: 深入浅出javascript

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

上一篇:网络传输协议(http协议)(网络传输协议是事实上的国际标准)

下一篇:javaScript语法总结(javascript语法术语)

  • 动迁补偿款怎么算
  • 用友删除凭证后期初余额不对
  • 技术支持费用取费依据
  • 非居民劳务个税怎么计算
  • 研发费用可以结转以后年度抵扣吗对吗
  • 购进农产品取得3%专票怎样计算抵扣举例
  • 临时占用耕地可以种树吗
  • 公司注销时应付职工薪酬怎么处理
  • 造价服务费收费标准计算器
  • 会计凭证的概念及分类
  • 10个点的发票税点开6个点专票
  • 个人名义帮公司贷款
  • 小规模企业给别人开16万增值税专用发票
  • 一般纳税人两费减免会计分录
  • 出口退税信息系统
  • 未开票增值税怎么申报
  • 转账时开户行写错了钱转出去了对方收不到
  • 税务没有核定印花税
  • 固定资产核销怎么做
  • 支付拆迁补偿款做账
  • mac更新系统版本
  • 结转完工产品成本的公式
  • windows7的笔记本有哪些
  • linux怎么开启远程
  • 联想昭阳k41笔记本
  • 营业外收入账户贷方登记企业发生的各项营业外收入
  • 前端页面出现乱码
  • 结转完工工程成本是什么
  • 财务报表的组成部分
  • 什么情况下可以土葬
  • 公司借款利息可以用对公户转账吗
  • 动力和燃料的区别
  • 废旧物资回收税收优惠政策2022
  • 社保基数和实际工资怎么算
  • 房地产企业销售佣金税前扣除
  • php mysql_real_escape_string addslashes及mysql绑定参数防SQL注入攻击
  • three.js如何给模型锚点
  • 发现新大陆的是麦哲伦还是哥伦布
  • nodejs搭建http服务器接收请求
  • 债券发行的分录
  • 对公银行卡账户
  • 员工旅游的费用账务处理
  • 减免税额和抵免税额是什么意思
  • 房租押金不退还的账务怎么处理
  • SQL查询数据库中表的某一列
  • 财务软件期末处理
  • 购买财务软件报税流程
  • 无票收入要交企业所得税吗
  • sql server获取字段长度
  • 商业购进商品运费怎么算
  • 购买固定资产进项税现金流量
  • 退货开增值税专票可以用负数吗
  • 福利费发票抵扣了有什么后果
  • 企业增加实收资本的途径不包括
  • 现金日记账谁负责
  • 购买股票如何操作
  • 餐饮企业老板
  • 人力资源公司的盈利模式
  • 出口退税登记的内容
  • 税控盘没有反写会罚款吗
  • 领购发票的方式有哪些
  • 删除mysql数据库中表的内容命令
  • windows server 2003 standard
  • Fedora Core 4.0 安装图解
  • windows8怎么设置
  • mac电脑卡死按哪三个键
  • linux wordpress gzip压缩开启方法
  • Win7 64位旗舰版设置字体显示比例让字体变大
  • window7系统中的桌面指什么
  • 从头开始绘制一幅画图片
  • 下载一个网页的所有图片
  • mono为什么不能用了
  • Node.js 中exports 和 module.exports 的区别
  • 广西的高速怎么一段收费一段不收费
  • 快递公司开票
  • 乾隆年间财政收入统计表
  • 重庆国税电子税务局
  • 税务局风险防控工作总结
  • 国家税务局增值税发票平台
  • 怎么查税务是否注销成功
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设