位置: 编程技术 - 正文

javascript从作用域链谈闭包(javascript的作用域)

编辑:rootadmin

推荐整理分享javascript从作用域链谈闭包(javascript的作用域),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:简要说明javascript的作用,javascript的主要作用,简要说明javascript的作用,请问在javascript程序中,简要说明javascript的作用,javascript的作用域,javascript运用,javascript 作用,内容如对您有帮助,希望把文章链接给更多的朋友!

神马是闭包关于闭包的概念,是婆说婆有理。

闭包是指有权访问另外一个函数作用域中的变量的函数这概念有点绕,拆分一下。从概念上说,闭包有两个特点:

1、函数 2、能访问另外一个函数作用域中的变量

在ES 6之前,Javascript只有函数作用域的概念,没有块级作用域(但catch捕获的异常 只能在catch块中访问)的概念(IIFE可以创建局部作用域)。每个函数作用域都是封闭的,即外部是访问不到函数作用域中的变量。

但是为了得到美女的名字,不死心的单身汪把代码改成了这样:

这下,美女是一个闭包了,单身汪想怎么玩就怎么玩了。(但并不推荐单身汪用中文做变量名的写法,大家不要学)。

关于闭包呢,还想再说三点: 1、闭包可以访问当前函数以外的变量

getDate是一个闭包,该函数执行时,会形成一个作用域A,A中并没有定义变量date,但它能在父一级作用域中找到该变量的定义。

2、即使外部函数已经返回,闭包仍能访问外部函数定义的变量

3、闭包可以更新外部变量的值

作用域链为毛闭包就能访问外部函数的变量呢?这就要说说Javascript中的作用域链了。 Javascript中有一个执行环境(execution context)的概念,它定义了变量或函数有权访问的其它数据,决定了他们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。你可以把它当做Javascript的一个普通对象,但是你只能修改它的属性,却不能引用它。

变量对象也是有父作用域的。当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不再存在父作用域了,这就是作用域链。

作用域链和原型继承有点类似,但又有点小区别:如果去查找一个普通对象的属性时,在当前对象和其原型中都找不到时,会返回undefined;但查找的属性在作用域链中不存在的话就会抛出ReferenceError。

作用域链的顶端是全局对象。对于全局环境中的代码,作用域链只包含一个元素:全局对象。所以,在全局环境中定义变量的时候,它们就会被定义到全局对象中。当函数被调用的时候,作用域链就会包含多个作用域对象。

全局环境

关于作用域链讲得略多(红皮书上有关于作用域及执行环境的详细解释),看一个简单地例子:

javascript从作用域链谈闭包(javascript的作用域)

在全局环境中,创建了两个简单地变量。如前面所说,此时变量对象是全局对象。

Non-nested functions

改动一下代码,创建一个没有函数嵌套的函数:

当myFunc被定义的时候,myFunc的标识符(identifier)就被加到了当前的作用域对象中(在这里就是全局对象),并且这个标识符所引用的是一个函数对象(function object)。函数对象中所包含的是函数的源代码以及其他的属性。其中一个我们所关心的属性就是内部属性[[scope]]。[[scope]]所指向的就是当前的作用域对象。也就是指的就是函数的标识符被创建的时候,我们所能够直接访问的那个作用域对象(在这里就是全局对象)。

比较重要的一点是:myFunc所引用的函数对象,其本身不仅仅含有函数的代码,并且还含有指向其被创建的时候的作用域对象。

当myFunc函数被调用的时候,一个新的作用域对象被创建了。新的作用域对象中包含myFunc函数所定义的本地变量,以及其参数(arguments)。这个新的作用域对象的父作用域对象就是在运行myFunc时我们所能直接访问的那个作用域对象。

Nested functions

如前面所说,当函数返回没有被引用的时候,就会被垃圾回收器回收。但是对于闭包(函数嵌套是形成闭包的一种简单方式)呢,即使外部函数返回了,函数对象仍会引用它被创建时的作用域对象。

当调用createCounter()时,内嵌函数increment和get都有指向createCounter() scope的引用。如果createCounter()没有任何返回值,那么createCounter() scope不再被引用,于是就可以被垃圾回收。但是因为createCounter()实际上是有返回值的,并且返回值被存储在了myCounter中,所以对象之间的引用关系发生变化。

需要用点时间思考的是:即使createCounter()已经返回,但是其作用域仍在,并能且只能被内联函数访问。可以通过调用myCounter.increment() 或 myCounter.get()来直接访问createCounter()的作用域。

当myCounter.increment() 或 myCounter.get()被调用时,新的作用域对象会被创建,并且该作用域对象的父作用域对象会是当前可以直接访问的作用域对象。

当执行到return counter;时,在get()所在的作用域并没有找到对应的标示符,就会沿着作用域链往上找,直到找到变量counter,然后返回该变量,调用increment(5)则会更有意思。当单独调用increment(5)时,参数value会存贮在当前的作用域对象。函数要访问value,能马上在当前作用域找到该变量。但是当函数要访问counter时,并没有找到,于是沿着作用域链向上查找,在createCounter()的作用域找到了对应的标示符,increment()就会修改counter的值。除此之外,没有其他方式来修改这个变量。闭包的强大也在于此,能够存贮私有数据。

Similar function objects, different scope objects对于上面的counter示例,再说点扩展的事。看代码:

myCounter1 和 myCounter2创建之后,关系图是酱紫的:

在上面的例子中,myCounter1.increment和myCounter2.increment的函数对象拥有着一样的代码以及一样的属性值(name,length等等),但是它们的[[scope]]指向的是不一样的作用域对象。

这才有了下面的结果:

作用域和this作用域会存储变量,但this并不是作用域的一部分,它取决于函数调用时的方式。关于this指向的总结,可以看这篇文章:JavaScript面试问题:事件委托和this

js为什么不能正确处理小数运算? varsum=0;for(vari=0;i;i++){sum+=0.1;}console.log(sum);上面的程序会输出1吗?在你有必要知道的个JavaScript面试题一文中,第8个题浅显的说了下js为什么不能正确

js+css简单实现网页换肤效果 本文实例讲述了js+css简单实现网页换肤效果。分享给大家供大家参考,具体如下:这里做了3套外观,分别使用不同文件夹下的同名css文件,那么怎样实

javascript实现下拉提示选择框 本文介绍了select和sugget结合起来使用的例子,支持下拉的直接选择,也支持在下拉内容中输入过滤。整体效果就是下面这样的:1、首先需要引入如下文

标签: javascript的作用域

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

上一篇:你有必要知道的25个JavaScript面试题(你知道必要的意思吗英文)

下一篇:js为什么不能正确处理小数运算?(js为什么不能用var定义变量)

  • 开专票了还能不能退款
  • 报废车残值款计入什么科目
  • 二手车交啥税
  • 直接收到货款也要走应收账款吗
  • 科技公司的成本如何核算
  • 对公账户的钱能转到私人账户吗
  • 转让不动产取得的发票
  • 接受非货币性资产捐赠以其什么确认捐赠额
  • 一般纳税人税种认定有几个增值税要怎么申报呀
  • 公司的样品一般怎么处理
  • 房屋租赁发票可以抵扣增值税吗
  • 小规模没有进项票可以开销项票吗
  • 无产权的建筑出售怎么办
  • 老会计有多厉害
  • 费用无发票财务怎么做账
  • 海关年检需要什么资料
  • 物流公司的保险服务属于什么费用
  • 奖金能否和工资一起发放
  • 买新车抵旧车
  • 小规模纳税人专票开3%的专票,以后就不能享受1%
  • 金税盘月末做哪些事情
  • 无法支付的款项转销
  • 工厂产品研发代码是多少
  • xmp是什么格式的文件是一种预设吗
  • rundll32进程很多
  • 多缴纳税款
  • 小规模纳税人差额征税
  • php require的用法
  • PHP:mcrypt_decrypt()的用法_Mcrypt函数
  • 公司购买邮票计入什么科目
  • 火灾造成存货损失应该作为报废还是盘亏
  • 最小的蓝牙鼠标是哪款
  • 长期股权投资的账面价值怎么计算
  • 出口换汇成本一般是多少
  • Yii2 rbac权限控制操作步骤实例教程
  • 增值税专用发票的税率是多少啊
  • 以前年度的销售退回,冲减哪年的
  • vue结合elementui
  • 微信小程序实现文件上传
  • vuecli怎么使用自定义组件
  • 一般纳税人和小规模
  • php登录不了
  • 织梦自适应模板怎么弄
  • 福利费为什么通过应付职工薪酬科目要紧吗
  • 子公司借钱给母公司,未收取利息,要纳税吗
  • 营改增后建筑企业财务核算
  • 年均复合增长率该怎么算?
  • 社保滞纳金所得税
  • 购买火车票报销,实际没乘车能查到嘛
  • 个人所得税部分缴款怎么算
  • 报销差旅费大于预借差旅费会计分录
  • 收到残保金退税现金流
  • 虚购发票进项税怎么处理
  • 非正常损失进项税额转出怎么计算
  • 一般纳税人月销售额10万以下
  • 小企业会计准则2023电子版
  • 房地产开发费用10%
  • 弱电系统可以入户门吗
  • 会务费所需要注意的细节
  • 在sqlserver2008中
  • w10 2021年更新
  • nhaspx.exe是什么
  • Slackware Linux init 进程
  • win7开机每次都要输入用户名
  • dos怎么开启
  • [置顶]bilinovel
  • 安卓游戏模拟游戏制作
  • html中href,src区别
  • 作用
  • jquery 引入js
  • unity如何调整界面
  • python获取本地路径
  • jquery中遍历指定的对象和数组是哪个方法
  • jquery实现图片横向移动
  • jquery有自定义选择器吗
  • jQuery通过ajax请求php遍历json数组到table中的代码(推荐)
  • 15个值得开发人是谁
  • 江西省发票综合服务平台
  • 宁夏地税领导班子名单
  • 重庆市国税网官方网站
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设