js高端系列教程(24)——执行上下文其三:闭包 Closures

js高端系列教程(24)——执行上下文其三:闭包 Closures

ID:40558949

大小:44.47 KB

页数:4页

时间:2019-08-04

js高端系列教程(24)——执行上下文其三:闭包 Closures_第1页
js高端系列教程(24)——执行上下文其三:闭包 Closures_第2页
js高端系列教程(24)——执行上下文其三:闭包 Closures_第3页
js高端系列教程(24)——执行上下文其三:闭包 Closures_第4页
资源描述:

《js高端系列教程(24)——执行上下文其三:闭包 Closures》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、闭包(Closures)在ECMAScript中,函数是“第一类”对象。这个名词意味着函数可以作为参数被传递给其他函数使用(在这种情况下,函数被称为“funargs”——“functionalarguments”的缩写[译注:这里不知翻译为泛函参数是否恰当])。接收“funargs”的函数被称之为高阶函数(higher-orderfunctions),或者更接近数学概念的话,被称为运算符(operators)。其他函数的运行时也会返回函数,这些返回的函数被称为functionvalued函数(有functionalvalue的函数)

2、。“funargs”与“functionalvalues”有两个概念上的问题,这两个子问题被称为“Funargproblem”(“泛函参数问题”)。要准确解决泛函参数问题,需要引入闭包(closures)到的概念。让我们仔细描述这两个问题(我们可以见到,在ECMAScript中使用了函数的[[Scope]]属性来解决这个问题)。“funargproblem”的一个子问题是“upwardfunargproblem”[译注:或许可以翻译为:向上查找的函数参数问题]。当一个函数从其他函数返回到外部的时候,这个问题将会出现。要能够在外部上下

3、文结束时,进入外部上下文的变量,内部函数在创建的时候(atcreationmoment)需要将之存储进[[Scope]]属性的父元素的作用域中。然后当函数被激活时,上下文的作用域链表现为激活对象与[[Scope]]属性的组合(事实上,可以在上图见到):Scopechain=Activationobject+[[Scope]]作用域链=活动对象+[[Scope]]请注意,最主要的事情是——函数在被创建时保存外部作用域,是因为这个被保存的作用域链(savedscopechain)将会在未来的函数调用中用于变量查找。functionfoo

4、(){varx=10;returnfunctionbar(){console.log(x);};}//"foo"返回的也是一个function//并且这个返回的function可以随意使用内部的变量xvarreturnedFunction=foo();//全局变量"x"varx=20;//支持返回的functionreturnedFunction();//结果是10而不是20这种形式的作用域称为静态作用域[static/lexicalscope]。上面的x变量就是在函数bar的[[Scope]]中搜寻到的。理论上来说,也会有动态作用

5、域[dynamicscope],也就是上述的x被解释为20,而不是10.但是EMCAScript不使用动态作用域。“funargproblem”的另一个类型就是自上而下[”downwardfunargproblem”].在这种情况下,父级的上下会存在,但是在判断一个变量值的时候会有多义性。也就是,这个变量究竟应该使用哪个作用域。是在函数创建时的作用域呢,还是在执行时的作用域呢?为了避免这种多义性,可以采用闭包,也就是使用静态作用域。请看下面的例子://全局变量"x"varx=10;//全局functionfunctionfoo(){

6、console.log(x);}(function(funArg){//局部变量"x"varx=20;//这不会有歧义//因为我们使用"foo"函数的[[Scope]]里保存的全局变量"x",//并不是caller作用域的"x"funArg();//10,而不是20})(foo);//将foo作为一个"funarg"传递下去从上述的情况,我们似乎可以断定,在语言中,使用静态作用域是闭包的一个强制性要求。不过,在某些语言中,会提供动态和静态作用域的结合,可以允许开发员选择哪一种作用域。但是在ECMAScript中,只采用了静态作用域。

7、所以ECMAScript完全支持使用[[Scope]]的属性。我们可以给闭包得出如下定义:Aclosureisacombinationofacodeblock(inECMAScriptthisisafunction)andstatically/lexicallysavedallparentscopes.Thus,viathesesavedscopesafunctionmayeasilyreferfreevariables.闭包是一系列代码块(在ECMAScript中是函数),并且静态保存所有父级的作用域。通过这些保存的作用域来搜寻到

8、函数中的自由变量。请注意,因为每一个普通函数在创建时保存了[[Scope]],理论上,ECMAScript中所有函数都是闭包。还有一个很重要的点,几个函数可能含有相同的父级作用域(这是一个很普遍的情况,例如有好几个内部或者全局的函数)

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。