《AS3 Expert》动态语言的基石:函数闭包


Admin
2010年6月19日名人名言:时间,每天得到的都是二十四小时,可是一天的时间给勤勉的人带来智慧和力量,给懒散的人只留下一片悔恨。——鲁迅

原文:http://sban.biz/216

闭包(Closure)是函数(或方法)及其执行环境的组合体,它不仅包括函数(或方法)本身,也包括函数(或方法)运行时的上下文词汇环境。闭包是所有动态语言的基石,闭包实现了函数(或方法)可以作为参数传递给函数(或方法)。

1,用一个代码实验例示闭包概念

在AS3中,共种三种闭包:

1)函数闭包(Function Closure)

2)方法闭包(Method Closure)

3)类闭包(Class Closure)

public class Closure extends Sprite{   public function Closure() {     super();      init();   }

   private var author :String = "sban";   private var onMouseClick2 :Function = function(e :MouseEvent) : void     {         trace("author:" + author, "this:" + this);//author:undefined this:[object global]       };

  private function init() :void {     var onMouseClick1 : Function = function(e :MouseEvent) : void            {             trace("author:" + author, "this:" + this);//author:sban this:[object global]            };        this.stage.addEventListener(MouseEvent.CLICK, onMouseClick2); }

   private function onMouseClick(e :MouseEvent) :void    {     trace("author:" + author, "this:" + this);//author:sban this:[object Closure]   }

}

在上例代码中,分别以onMouseClick,onMouseClick1,onMouseClick2为listener向stage添加click事件监听,trace结果如代码中注释。其中,onMouseClick是方法闭包,onMouseClick1与onMouseClick2是函数闭包。这里有一个问题,为什么在onMouseClick2中author的输出结果是undefined?

2,三类闭包的区分

在AS3中,任何一个函数(或方法)调用,至少会有一个this参数,这几乎是所有动态语言一惯的规则,不同的是,有的语言对程序员是可见的,如Python,有的则不可见,如AS3。

1) 方法闭包

所有类实例的方法,作为参数传递时,均是方法闭包,隐匿的第一个this参数永远是类实例本身,如上例代码中的onMouseClick便是方法闭包,所以它的this输出为[object Closure]。

2) 函数闭包

所有匿名方法(包括局部变量方法,类变量方法,见上),全局方法(包括位于根包下的全局方法,位于子包下的全局方法,见下)均是函数闭包,所有函数闭包的第一个函数如果是null,将被默认替换为Global对象,所以我们看到的输出均是[object global] 。

package{    import flash.events.MouseEvent;

 function onMouseClick3(e :MouseEvent) :void   {     trace("this:" + this);//this:[object global]   }}

package sban.as3Expert{ import flash.events.MouseEvent;

 public function onMouseClick4(e :MouseEvent)  {     trace("this:" + this);//this:[object global]   }}

对于位于子包下的函数,可以这样直接使用:

this.stage.addEventListener(MouseEvent.CLICK, sban.as3Expert.onMouseClick4);

3)类闭包

这是三类闭包中最简单的一种,也是最容易区分的一种,可能也是价值最低的一种,貌似根本不应该归为闭包类别。在AS3中,所有显式对象类型转换均是类闭包,如下:

//if obj is Closure which type anotation is Objectvar obj1 :Closure = Closure(obj);

Closure在这里不是操作符,也不是别的什么东西,在这里应该把它理解为一个特殊的方法。这个方法第一个参数仍然为this,第二个参数是将被作类型转换的对象,在上例代码中为obj。

3,改变函数闭包的this参数的一种情况

在函数闭包中,this参数(null)通常被默默置换为global对象,在某些情况下,程序员可以传递真实的this参数进去,而不是null,从而避免被替换为global对象。

在Array的forEach, every, map, some, filter这些API中,第一个参数为函数对象,第二个参数为第一个参数的this对象,当程序员指定第二个参数时,便可以在第一个函数内访问this上下文环境的变量,如果不指定,便不能再其内使用this。

public function ArrayForEachThis(){   super();

    var arr :Array = [1,2,3];    arr.forEach(      function (item :int,index :int=-1,arr :Array = null) :void      {         trace(item, this.author)      }     //,this   );}

private var author :String = "sban";

编码规范:在使用Array的forEach, every, map, some, filter这些API时,必须在第二个参数位传递this进去。

4,为什么在onMouseClick2中author的输出是undefined?

所有AS3程序员都应当知道,在AS3运行时,有一个作用域链,该作用域链自global始,在运行时变量首先从最近的链点查找,如果未找到,再向上查找,直到找到或到达global链点。

onMouseClick2函数的运行时作用域链为:

onMouseClick2闭包->global

在这个链条内,根本不存在author变量,所以onMouseClick2的输出为undefined。

而onMouseClick1的作用域链为:

onMouseClick1->init->Closure->global

onMouseClick的作用域链为:

onMouseClick->Closure->global

这两个作用域链均包括author变量,所以onMouseClick1与onMouseClick均不会输出undefined。

作用域链的节点包括闭包对象,但不仅包括它。

sban 2009/5/15 北京。转载请注明作者及出处,非商用。

  • E4X用法简要
  • 命名空间:如何控制未知方法的调用
  • 变量及作用域
  • Traits对象:为什么静态方法不能被继承
  • 像Ruby一样简易行码:使用Prototype扩展原生对象
  • Flash Player的垃圾内存回收机制:能否强制回收?
  • AS3中的一些基本定义,Function与Method的区别
  • AS3中的八种基元类型
  • 在AS3中,如何实现数组及对象的深拷贝?
  • 如何让if语言写的更简洁?(七种布尔转换为假的情况总结)
作者:sban

出处:http://sban.biz

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。


时间,每天得到的都是二十四小时,可是一天的时间给勤勉的人带来智慧和力量,给懒散的人只留下一片悔恨。——鲁迅
来源:http://www.cnblogs.com/sban/archive/2010/05/27/1745357.html

补充可有意思的例子:
package
{import flash.display.Sprite;import flash.events.MouseEvent;public class Main extends Sprite{public function Main(){//func1(2);//func1(3);var b:int=1;func1(b);b++;func1(b);}public function func1(a:int):void{stage.addEventListener(MouseEvent.CLICK,func2);function func2(e:MouseEvent):void{trace(a);}return;}}
}

在场景上按一下,结果:

1

2

充分说明了运行时保存上下文环境的特性。

转载于:https://www.cnblogs.com/wonderKK/archive/2012/08/01/2618800.html

(转)《AS3 Expert》动态语言的基石:函数闭包相关推荐

  1. 【Groovy】Groovy 动态语言特性 ( Groovy 中函数实参自动类型推断 | 函数动态参数注意事项 )

    文章目录 前言 一.Groovy 中函数实参自动类型推断 二.函数动态参数注意事项 三.完整代码示例 前言 Groovy 是动态语言 , Java 是静态语言 ; 本篇博客讨论 Groovy 中 , ...

  2. 【C 语言】动态库封装与设计 ( 动态库调用环境搭建 | 创建应用 | 拷贝动态库相关文件到源码路径 | 导入头文件 | 配置动态库引用 | 调用动态库中的函数 )

    文章目录 一.在 Visual Studio 2019 中创建 " 控制台应用 " 程序 二.拷贝 xxx.lib.xxx.dll.xxx.h 到源码路径 三.导入 xxx.h 头 ...

  3. c语言malloc用法 数组,详解C语言用malloc函数申请二维动态数组的实例

    详解C语言用malloc函数申请二维动态数组的实例 C语言在程序运行中动态的申请及释放内存十分方便,一维数组的申请及释放比较简单. Sample one #include int main() { c ...

  4. C语言调用Go生成的动态库中的函数

    工作中遇到的Go语言调用C函数的场景比较多,之前也写过一篇<cgo中将C函数返回的数组转为Go中的slice>. 目前在开发OpenSIPS的过程中,有些功能用C写起来麻烦,故第一次尝试了 ...

  5. 动态语言的灵活性是把双刃剑 -- 以Python语言为例

    本文有些零碎,总题来说,包括两个问题: (1)可变对象(最常见的是list dict)被意外修改的问题, (2)对参数(parameter)的检查问题. 这两个问题,本质都是因为动态语言(动态类型语言 ...

  6. 高并发大流量专题---8、动态语言的并发处理

    高并发大流量专题---8.动态语言的并发处理 一.总结 一句话总结: 和本科毕业论文连起来了:基于消息中间件Rocket MQ的研究:用于并发处理的消息队列 1.什么是进程.线程.协程? 进程(Pro ...

  7. 为什么php动态语言,动态语言静态化

    [TOC] ## 什么是动态语言静态化 将现有PHP等动态语言的逻辑代码生成为静态HTML文件,用户访问动态脚本重定向到静态HTML文件的过程. 对实时性要求不高的页面 ## 为什么要静态化 动态脚本 ...

  8. 为什么说Python是一门动态语言--Python的魅力

    动态语言的定义:动态编程语言是高级程序设计语言的一个类别,在计算机科学领域已被广泛应用. 它是一类在执行时能够改变其结构的语言:比如新的函数.对象.甚至代码能够被引进,已有的函数能够被删除或是其它结构 ...

  9. 为什么可以说Java语言是准动态语言?

    什么是动态语言? 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如JavaScript便是一个典型的动态语言. 除此之外如Ruby.Python ...

最新文章

  1. linux安装oracle常见错误 总结
  2. GIT 团队协作快速入门使用
  3. 【鬼网络】之DHCP原理与配置
  4. 成长 | 《大厂晋升指南》学习总结(上)
  5. 【PhotoScan精品教程】任务一:新建工程、导入照片、设置坐标系、导入控制点(POS)、自由空三
  6. 数据透视表和数据交叉表_数据透视表的数据提取
  7. mac11.14 mysql_mysql 5.7 11 章 数据类型(1)
  8. 函数头文件php_PHP 7.4 的 FFI 将支持更好地在 PHP 中使用 C 函数/数据结构
  9. loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)
  10. 【经典】Noip动态规划
  11. Win10人脉应用将关闭与新浪微博关联
  12. fiddler响应中文乱码问题
  13. 202102 sqlplus command not found 注意切换用户
  14. bzoj1005 [HNOI2008]明明的烦恼(Prufer数列+高精度(wys算法。。。))
  15. 动手打造N合1操作系统安装光盘
  16. pytorch蜜蜂蚂蚁数据集处理python代码
  17. 天道酬勤,记春招之路(完美世界,360,腾讯IEG,网易雷火)
  18. Stale branches 设置_手机资讯:iPhone 如何设置来电闪光灯苹果手机 LED 灯来电提醒设置教程...
  19. python 安装dmPython
  20. 谜样的计算机科学之父

热门文章

  1. MySql安装及Navicat连接(解决Starting the server失败;mysql输入密码登录报错1045(28000),不输入密码却能登录;Navicat连接报错2059)
  2. 弗吉尼亚理工计算机科学排名,2020年弗吉尼亚理工大学排名TFE Times美国最佳计算机科学硕士专业排名第45...
  3. 循环码差错图样matlab,基于MATLAB的(15,7)循环码的编译仿真.doc
  4. ef mysql dbfirst,.NetCore教程之 EFCore連接Mysql DBFirst模式
  5. UE4学习-使用蓝图进行一个关卡的设计
  6. ajax怎么在html与php中使用,如何使用ajax和php将数据从数据库表放到html表
  7. 深度探索linux系统虚拟化 原理与实现,深度探索Linux系统虚拟化:原理与实现
  8. postgres xshell copy 命令 内存溢出_良心国产工具,比Xshell好用还免费!
  9. “搬砖”机器人,每小时800块!
  10. 史上卖得最多的芯片......原来是这个!