位置: 编程技术 - 正文

深入理解javascript作用域和闭包(深入理解新发展理念,推进供给侧结构性改革 心得体会)

编辑:rootadmin

推荐整理分享深入理解javascript作用域和闭包(深入理解新发展理念,推进供给侧结构性改革 心得体会),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:深入理解中国式现代化,深入理解中国式现代化,深入理解计算机系统,深入理解新发展理念,深入理解javascript,深入理解计算机系统,深入理解计算机系统,深入理解javascript,内容如对您有帮助,希望把文章链接给更多的朋友!

作用域

作用域是一个变量和函数的作用范围,javascript中函数内声明的所有变量在函数体内始终是可见的,在javascript中有全局作用域和局部作用域,但是没有块级作用域,局部变量的优先级高于全局变量,通过几个示例来了解下javascript中作用域的那些“潜规则”(这些也是在前端面试中经常问到的问题)。

1. 变量声明提前示例1:

此处的输出是undefined,并没有报错,这是因为在前面我们提到的函数内的声明在函数体内始终可见,上面的函数等效于:

注意,如果忘记var,那么变量就被声明为全局变量了。

2. 没有块级作用域

和其他我们常用的语言不同,在Javascript中没有块级作用域:

在javascript中变量的作用范围是函数级的,即在函数中所有的变量在整个函数中都有定义,这也带来了一些我们稍不注意就会碰到的“潜规则”:

在①处输出的值竟然是undefined,简直丧心病狂啊,我们已经定义了全局变量的值啊,这地方不应该为hello吗?其实,上面的代码等效于:

声明提前、全局变量优先级低于局部变量,根据这两条规则就不难理解为什么输出undefined了。

作用域链

在javascript中,每个函数都有自己的执行上下文环境,当代码在这个环境中执行时,会创建变量对象的作用域链,作用域链是一个对象列表或对象链,它保证了变量对象的有序访问。作用域链的前端是当前代码执行环境的变量对象,常被称之为“活跃对象”,变量的查找会从第一个链的对象开始,如果对象中包含变量属性,那么就停止查找,如果没有就会继续向上级作用域链查找,直到找到全局对象中:

作用域链的逐级查找,也会影响到程序的性能,变量作用域链越长对性能影响越大,这也是我们尽量避免使用全局变量的一个主要原因。

闭包

基础概念作用域是理解闭包的一个前提,闭包是指在当前作用域内总是能访问外部作用域中的变量。

深入理解javascript作用域和闭包(深入理解新发展理念,推进供给侧结构性改革 心得体会)

上面的示例在函数中返回了两个闭包,这两个闭包都维持着对外部作用域的引用,因此不管在哪调用总是能够访问外部函数中的变量。在一个函数内部定义的函数,会将外部函数的活跃对象添加到自己的作用域链中,因此上面实例中通过内部函数能够访问外部函数的属性,这也是javascript模拟私有变量的一种方式。

注意:由于闭包会额外的附带函数的作用域(内部匿名函数携带外部函数的作用域),因此,闭包会比其它函数多占用些内存空间,过度的使用可能会导致内存占用的增加。

闭包中的变量

在使用闭包时,由于作用域链机制的影响,闭包只能取得内部函数的最后一个值,这引起的一个副作用就是如果内部函数在一个循环中,那么变量的值始终为最后一个值。

上面的程序并没有按照我们预期的输入1-5的数字,而是5次全部输出了5。再来看一个示例:

调用createClosure()[0]()返回的是5,createClosure()[4]()返回值仍然是5。通过以上两个例子可以看出闭包在带有循环的内部函数使用时存在的问题:因为每个函数的作用域链中都保存着对外部函数(timeManage、createClosure)的活跃对象,因此,他们都引用着同一变量i,当外部函数返回时,此时的i值为5,所以内部的每个函数i的值也为5。那么如何解决这个问题呢?我们可以通过匿名包裹器(匿名自执行函数表达式)来强制返回预期的结果:

或者在闭包匿名函数中再返回一个匿名函数赋值:

无论是匿名包裹器还是通过嵌套匿名函数的方式,原理上都是由于函数是按值传递,因此会将变量i的值复制给实参num,在匿名函数的内部又创建了一个用于返回num的匿名函数,这样每个函数都有了一个num的副本,互不影响了。

闭包中的this

在闭包中使用this时要特别注意,稍微不慎可能会引起问题。通常我们理解this对象是运行时基于函数绑定的,全局函数中this对象就是window对象,而当函数作为对象中的一个方法调用时,this等于这个对象(TODO 关于this做一次整理)。由于匿名函数的作用域是全局性的,因此闭包的this通常指向全局对象window:

调用object.getScope()()返回值为global而不是我们预期的local,前面我们说过闭包中内部匿名函数会携带外部函数的作用域,那为什么没有取得外部函数的this呢?每个函数在被调用时,都会自动创建this和arguments,内部匿名函数在查找时,搜索到活跃对象中存在我们想要的变量,因此停止向外部函数中的查找,也就永远不可能直接访问外部函数中的变量了。总之,在闭包中函数作为某个对象的方法调用时,要特别注意,该方法内部匿名函数的this指向的是全局变量。

幸运的是我们可以很简单的解决这个问题,只需要把外部函数作用域的this存放到一个闭包能访问的变量里面即可:

内存与性能

由于闭包中包含与函数运行期上下文相同的作用域链引用,因此,会产生一定的负面作用,当函数中活跃对象和运行期上下文销毁时,由于必要仍存在对活跃对象的引用,导致活跃对象无法销毁,这意味着闭包比普通函数占用更多的内存空间,在IE浏览器下还可能会导致内存泄漏的问题,如下:

上面例子中匿名函数对外部对象target产生一个引用,只要是匿名函数存在,这个引用就不会消失,外部函数的target对象也不会被销毁,这就产生了一个循环引用。解决方案是通过创建target.name副本减少对外部变量的循环引用以及手动重置对象:

闭包中如果存在对外部变量的访问,无疑增加了标识符的查找路径,在一定的情况下,这也会造成性能方面的损失。解决此类问题的办法我们前面也曾提到过:尽量将外部变量存入到局部变量中,减少作用域链的查找长度。

总结:闭包不是javascript独有的特性,但是在javascript中有其独特的表现形式,使用闭包我们可以在javascript中定义一些私有变量,甚至模仿出块级作用域,但闭包在使用过程中,存在的问题我们也需要了解,这样才能避免不必要问题的出现。

再探JavaScript作用域 黄金守则第一条:js没有块级作用域(你可以自己闭包或其他方法实现),只有函数级作用域,函数外面的变量函数里面可以找到,函数里面的变量外面

Internet Explorer 浏览器介绍:别叫我IE 在上个星期,微软随Windows8.1正式推出了InternetExplorer的第一次预览版。这样,关于这款备受争议的web浏览器泄露版本的各种传闻也该休息了。我们现在

js类中获取外部函数名的方法与代码 比如我们要在一个类中设定一个方法可以根据调入一个方法保存在类变量中,等需要的时候可以通过访问类变量来得到。通常如果我们生成一个实例如

标签: 深入理解新发展理念,推进供给侧结构性改革 心得体会

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

上一篇:js变量、作用域及内存详解(js变量作用域)

下一篇:js类中获取外部函数名的方法与代码(外部js获取当前vue实例)

  • 可以按小型微利企业核算企业所得税吗
  • 实际负税计算公式
  • 我国增值税的纳税人是如何管理的
  • 小规模纳税人加油发票可以抵扣吗
  • 国库券利息收入计入利润总额吗
  • 出纳与会计现金对不上
  • 进口增值税可以抵税吗
  • 小规模纳税人未开票收入如何填申报表
  • 房地产公司支付工程款账务处理
  • 公司已倒闭
  • 手工账写错字怎么改呢
  • 机关单位工会经费的来源包括
  • 结余资金财政收回如何做账
  • 公司把贷款的钱转给个人
  • 个人独资企业可以不开公户吗
  • 劳务公司差额开票的方式有哪些
  • 乐器的税率
  • 公户转账给个人没有票
  • 个体户需要申报工资薪金吗
  • 增值税发票和电子发票都可以报销吗
  • 吸收合并企业的情形
  • 企业购买二手车需要缴纳哪些税
  • 财务报告成本
  • 系统升级为win11
  • 加计扣除的会计要素
  • 外贸公司进出口权办理流程
  • ubuntu系统怎么安装微信
  • 路由器网速慢怎么设置
  • 超率累进税率和超倍累进税率
  • php数组函数 菜鸟
  • 企业并购特殊性税务处理
  • layui iconfont
  • phpinfo() 中 Local Value(局部变量)Master Value(主变量) 的区别
  • 公司外部人员的差旅费入什么科目
  • 税率变更为13%的文件
  • 微信小程序入门指南
  • yii gridview
  • 面试学弟学妹问题
  • 逆算法怎么算
  • 增值税专用发票几个点
  • 售后租回租金怎么做账
  • 研发支出什么时候转管理费用
  • 固定资产清理如何申报增值税
  • c语言typedef的用法
  • js与或运算符
  • 防伪税款服务费抵扣
  • 季度对账单 怎么处理
  • 有限合伙企业成本费用抵扣
  • 交易性金融资产入账价值怎么计算
  • 退伍军人9000补助
  • 无形资产175加计扣除例题
  • 第三方代销什么意思
  • 实收资本为0可以运作吗?
  • 付款金额比发票金额少怎么办
  • 质保金可以先不开票吗
  • 月末结转各项费用支出479000
  • 进项税额抵扣是按税率分开抵扣吗
  • 关联方交易舞弊手段
  • windows锁定用户
  • ubuntu系统无法安装中文
  • windows server2012安装完没有桌面
  • win8系统怎么创建局域网
  • ubuntu下软件
  • window 删除服务
  • 华硕电脑升级win11
  • 红帽子在工地上是什么级别
  • windows mobile
  • 在linux中使用apache发布web服务时默认web站点
  • js函数详解
  • excel表限制
  • css鼠标移入显示
  • Python selenium爬取table
  • 原生js实现ajax步骤
  • 深入探讨换个说法怎么说
  • nodejs和jsp
  • node exit
  • linux shell脚本命令
  • 全面解析皮炎
  • 如何发挥人才作为第一资源 护理
  • 河南助学金申请表
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设