




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、javascript从作用域链谈闭包神马是闭包关于闭包的概念,是婆说婆有理。闭包是指冇权访问另外一个函数作用域中的变量的函数这概念有点绕,拆分一 2从概念上说,闭包有两个特点: 1、函数 2、能访问另外一个函数作用域中的变量在es 6之前,javascript只有函数作用域的概念,没有块级作用域(但calch 捕获的异常只能在catch块中访问)的概念(iife叮以创建局部作用域)。每 个函数作用域都是封闭的,即外部是访问不到函数作用域小的变量。function getname() var name = 美女的名字;console, log (name) ;/美女的名字function dis
2、playname() console, log (name) ; /扌艮错但是为了得到美女的名字,不死心的单身汪把代码改成了这样:function getname() var name = 美女的名字;fun cl i on displaynameo console log(name);return displayname;var 美女二 getname ();美女()/美女的名字这下,美女是一个闭包了,单身汪想怎么玩就怎么玩了。(但并不推荐单身汪用 屮文做变量名的写法,大家不要学)。关于闭包呢,还想再说三点:1、闭包可以访问当前函数以外的变量 function getouter()var d
3、ate = ' 815,;function getdate(str)console. log(str + date) ; /访问外部的 datereturn getdate(j 今天是:/"今天是:815getouter ();getdate是一个闭包,该函数执行时,会形成一个作用域a, a中并没有定义变 量date,但它能在父一级作用域小找到该变量的定义。2、即使外部函数已经返回,闭包仍能访问外部函数定义的变量function getouter()var date 二'815'function getdate(str)console. log(str + d
4、ate) ; /访问外部的 datereturn getdate; /外部函数返冋var today 二 getouter();todayc今天是:/今天是:815today(j明天不是:);/"明天不是:8153、闭包可以更新外部变量的值function updatecount()var count = 0;function getcount(val)count = val;con sole, log (count);return gctcount;/外部函数返回var count = updatecount();count(815); /815count(816); /816作用
5、域链为毛闭包就能访问外部函数的变量呢?这就要说说javascript屮的作用域链 to_javascript屮有一个执行环境(execution context)的概念,它定义了变量或函 数冇权访问的其它数据,决定了他们各自的行为。每个执行环境都冇一个与z关 联的变量对彖,环境中定义的所有变量和函数都保存在这个对象中。你可以把它 当做javascript的一个普通对象,但是你只能修改它的属性,却不能引用它。变量对象也是有父作用域的。当访问一个变量时,解释器会首先在当前作用域查 找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不再 存在父作用域了,这就是作用域链。作用域链和原型
6、继承有点类似,但乂有点小区别:如果去查找一个普通对象的属 性吋,在当前对象和其原型屮都找不到时,会返冋undefined;但查找的属性在 作用域链中不存在的话就会抛出referenceerror0作用域链的顶端是全局对象。对于全局环境中的代码,作用域链只包含一个元索: 全局对象。所以,在全局环境中定义变量的时候,它们就会被定义到全局对象中。 当函数被调用的时候,作用域链就会包含多个作用域对象。全局环境关于作用域链讲得略多(红皮书上有关于作用域及执行环境的详细解释),看一个 简单地例子:/ my_script js "use strict" var foo 二 1;var b
7、ar 二 2;在全局环境小,创建了两个简单地变量。如前而所说,此时变量对象是全局对象。 non-nested functions改动一下代码,创建一个没有函数嵌套的函数:use strict"var foo = 1;var bar = 2; function myfunc() /- define 1ocal-to-function variablesvar a = 1;var b = 2;var foo = 3;console. log(/zinside myfunc);console. log(outside);/- and then, call it: myfunc ();当my
8、func被定义的时候,myfunc的标识符(identifier)就被加到了当前的作 用域对象中(在这里就是全局对象),并且这个标识符所引用的是一个函数对象 (function object)。函数对象小所包含的是函数的源代码以及其他的屈性。其中一个我们所关心的属性就是内部属性scopeo scope所指向的就是当 前的作用域对象。也就是指的就是函数的标识符被创建的时候,我们所能够直接 访问的那个作用域对象(在这里就是全局对象)。比较重要的一点是:myfunc所引用的函数对象,其本身不仅仅含冇函数的代码, 并且还含有指向其被创建的时候的作用域对象。当myfunc函数被调用的时候,一个新的作用域
9、对象被创建了。新的作用域对象 中包含myfunc函数所定义的本地变量,以及其参数(arguments)。这个新的作 用域对象的父作用域对象就是在运行myfunc时我们所能直接访问的那个作用域 对象。 nested functions如前面所说,当函数返回没有被引用的时候,就会被垃圾回收器回收。但是对于 闭包(函数嵌套是形成闭包的一种简单方式)呢,即使外部函数返回了,函数对 彖仍会引用它被创建时的作用域对彖。use strict"function creatccounter (initial) var counter = initial;function increment(value
10、) counter +二 value;function get () return counter;return increment: increment,get: get;var mycounter 二 createcounter (100);consol e. 1 og (mycounter. get () ; / 返回 100 mycountcr. incrcmcnt(5);console, log(mycounter. get() ; / 返回 105当调用createcounter (100)时,内嵌函数increment和get都冇指向 createcounter(100) sco
11、pe 的引用。如果 createcounter (100)没有任何返冋值, 那么createcounter (100) scope不再被引用,于是就可以被垃圾回收。但是因 为createcounter (100)实际上是冇返回值的,并且返回值被存储在了 mycounter 中,所以对象z间的引用关系发生变化。需要用点时间思考的是:即使createcounter (100)已经返回,但是-其作用域仍 在,并能且只能被内联函数访问。可以通过调用mycounter. increment()或 mycounter. get ()来直接访问 createcounter (100)的作用域。当mycoun
12、ter. increment ()或mycounter. get ()被调用时,新的作用域对象会 被创建,并且该作用域对象的父作用域对象会是当前可以直接访问的作用域对 彖。当执彳亍到return counter;时,在get ()所在的作用域并没有找到对应的标示符, 就会沿着作用域链往上找,直到找到变量counter,然后返回该变量,调用 increment (5)则会更冇意思。当单独调用increment (5)时,参数value会存贮 在当前的作用域对象。函数耍访问value,能马上在当前作用域找到该变量。但 是当函数要访问counter时,并没冇找到,于是沿着作用域链向上查找,在 cre
13、atecounter (100)的作用域找到了对应的标示符,increment ()就会修改 counter的值。除此之外,没有其他方式来修改这个变量。闭包的强大也在于此, 能够存贮私有数据。similar function objects, different scope objects 对于上面的counter示例,再说点扩展的事。看代码:/myscript js"use strict"function createcounter(initial) /* sec the code from previous example */- create counter obje
14、ctsvar mycounterl 二 createcounter(100);var mycounter2 二 createcounter(200);mycountcrl和mycountcr2仓u建之后,关系图是酱紫的:在上面的例子中,mycounterl. increment 和 mycounter2. increment 的函数对象 拥有着一样的代码以及一样的属性值(name, length等等),但是它们的scope 指向的是不一样的作用域对彖。这才冇了下而的结果:var a, b;a = mycounterl. get(); / b 二 mycounter2. gct() ; / mycounterl. incremen
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025姐弟车辆财产赠与合同
- 2025租赁承包合同范本
- 2025短期劳动合同范本【标准】
- 2025年门面租赁合同书范本
- 2025解除合同的劳动合同法规定
- 2025电梯租赁合同
- 《银屑病样皮炎》课件
- 《直肠癌护理》课件
- 《中国心理咨询发展史》课件
- 婴儿及儿童期癫痫及癫痫综合征的临床护理
- 甲亢病人护理讲课
- 2025年中国铜铝复合母线行业市场运行现状及投资战略研究报告
- (高清版)DB1331∕T 072-2024 《雄安新区高品质饮用水工程技术规程》
- 2025年金丽衢十二校高三语文第二次模拟联考试卷附答案解析
- 广东省深圳市福田区2023-2024学年六年级下学期英语期中试卷(含答案)
- 2023-2024学年广东省广州七中七年级(下)期中数学试卷(含答案)
- 2025年北京城市排水集团有限责任公司招聘笔试参考题库含答案解析
- 课件-2025年春季学期 形势与政策 第一讲-加快建设社会主义文化强国
- 2025年山东惠民县农业投资发展限公司招聘10人历年高频重点提升(共500题)附带答案详解
- 大学美育知到智慧树章节测试课后答案2024年秋长春工业大学
- 《基于嵌入式Linux的农业信息采集系统设计与研究》
评论
0/150
提交评论