位置: 编程技术 - 正文

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

  • 已认证进项税额转出会计分录账务处理
  • 售后回租和融资租赁账务处理
  • 一般纳税人服务费税率
  • 征收率 税率 区别
  • 专项扣除子女教育大学生可以吗
  • 园林绿化公司范围
  • 服务行业人工费计入什么科目
  • 金蝶专业版仓库反审核怎么做
  • 免抵退税申报资料情况表在哪下载
  • 是否独立核算取决于什么
  • 怎么把预付账款转到管理费用
  • 红字信息表状态是B900071
  • 公司股东投资比例
  • a3软件怎么反记账
  • 收到转账支票怎么去银行处理
  • 企业退回企业所得税分录
  • 外购动力的分录
  • 费用跨年入账所得怎么算
  • 工程投标保证金最新规定
  • 个人交的工会经费个税
  • 减免税期间是什么意思
  • 企业所得税汇算清缴时间
  • 新政府会计制度与旧制度区别
  • 外经证金额没开完需要核销吗
  • 工会上缴40%的经费法律依据
  • 上市公司股票下跌可以减持吗
  • Win11怎么设置自启动软件
  • 劳务公司怎么做进项
  • php字符转换成数字
  • 股东个人房产抵押贷款用于个人法人有责任么
  • 正爬上唐娜·诺克沙滩的灰海豹,英格兰北林肯郡 (© Frederic Desmette/Minden Pictures)
  • 增值税专用发票的税率是多少啊
  • 财政预算单位可以既是省级又是中央
  • 营业外支出准则
  • 什么是微前端
  • 帝国cms怎么用
  • 应交税费的分析应重点关注企业
  • 企业基金分红具备的条件
  • 个人增值税发票税率
  • 公司购买股东的东西
  • 本月损益类未结转为零的一级科目怎么操作
  • 事业单位破产清算开户流程
  • 公司注销开户许可证是不是要上交
  • 委托加工农产品的扣除率
  • 申报财产租赁合同怎么写
  • 实收资本怎么确认入账
  • 应收账款多收了退回怎么做账
  • 新办企业增多
  • 抄报返写
  • 简易计税项目可以抵扣进项税吗?
  • 企业办增项怎样办理
  • 优化sql语句10种方法
  • mysql工作内容
  • win10 win7兼容模式
  • 手把手教您安装软件
  • win8 设置
  • Netlib.exe - Netlib是什么进程 有什么用
  • linux sed
  • windows7 sp1升级包
  • 如何设置打开wincc不弹出项目管理
  • win8系统教程
  • minidump文件怎么打开
  • 电脑双系统删除一个系统的步骤
  • windows10 rs4
  • [置顶]bilinovel
  • unity如何操作
  • jquery validation
  • Python函数中仅允许有一条return语句
  • W3C Group的JavaScript1.8 新特性介绍
  • bootstraptable方法
  • javascript基于什么的语言
  • 英语流利说的简单介绍
  • 水利基金税率‰6什么时候调整
  • 重庆市电子税务局官网登录入口注册
  • 单位自有住房免增值税吗
  • 上海社保基数对照表
  • 宿迁市国家税务局徐友谅
  • 税务工作者发展现状
  • 天津市河东区税务局
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设