位置: 编程技术 - 正文

深入理解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实例)

  • 环保税申报表怎么填制
  • 非限定性净资产借贷方向
  • 企业租赁个人房屋怎么交税
  • 施工安全协议违约怎么办
  • 仓储费和仓储服务费的区别
  • 小规模纳税人购车是怎么抵税的
  • 社保扣除的是当月还是上个月的
  • 打款金额少于开票金额
  • 收到增值税专用发票是已经付款了吗
  • 境外增值税代扣代缴
  • 地方教育费附加的会计分录
  • 劳动合同解除和终止的经济补偿
  • 补交增值税如何入账
  • 职工教育经费进项
  • 一般纳税人如何纳税申报
  • 购买健身器材需要注意什么
  • 应交税费待抵扣进项税额是什么科目
  • 已经发货了点击确认收货可以吗?
  • 公共租赁住房的供应对象不包括
  • 在租的土地上建房
  • 税控设备指什么
  • 进项税和销项税怎么算
  • 应交企业所得税和所得税费用区别
  • 事业单位投资收回账务处理
  • 退税到账怎么做账
  • 栀子花的养殖方法和注意事项茉莉花
  • rtp webrtc
  • php实现的任意进程函数
  • 如何挽留婚姻危机
  • 交易性金融资产包括哪些项目
  • 使用php进行mysql数据库编程的基本步骤
  • vue项目运行报错
  • 差旅费误餐补贴标准
  • vue知识点总结
  • 百旺开票软件状态查询在哪里
  • 一般纳税人企业所得税税率2023
  • 金蝶系统采购发票
  • 现金支付的现状
  • 企业并购的主要特征是a扩大企业规模
  • 房屋租赁交的定金可以退吗
  • 小微企业利润表数据
  • 制造费用账户在月末一般没有余额
  • 小微企业是怎样自己认定的呢
  • 通货膨胀有什么表现
  • 社保费阶段性减免政策到什么时候
  • 哪些凭证可以作为原始凭证
  • 进项税额转出有什么好处
  • 置换房产流程
  • 对公账户分为几类
  • 备用金的支取流程图
  • 制造费用怎么结算
  • LNMP下使用命令行导出导入MySQL数据库的方法
  • ubuntu sudo apt-get install
  • 判断一个表是否存在
  • mysql 5.7.31安装
  • win7自带画图软件
  • window10桌面有白色框
  • xp系统怎么提升性能
  • 修改注册表解决画面撕裂
  • macbookair网页视频看不了
  • 如何确定我的学生学到了问题,尤其是核心素养方面
  • 苹果mac与平板的区别
  • win8触摸板失灵怎么办
  • iptables 增加
  • JAVAscript操作word
  • 游戏开发那些事
  • 实用的批处理命令
  • dos批处理实例800例
  • 全面理解和准确把握新时代党的建设总要求心得体会
  • ansible客户端需要装python
  • javascript的dom
  • unity3d做游戏
  • python中scipy用法
  • 港澳台资企业
  • 新疆国税局电子税务局
  • 出口退税的管理办法
  • 什么是新闻主管部门负责
  • 电子客票号码8768是什么
  • 消费税的税收筹划案例分析
  • 乡村振兴与文化遗产保护研究
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设