(转)《AS3 Expert》动态语言的基石:函数闭包
《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语言写的更简洁?(七种布尔转换为假的情况总结)
出处: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》动态语言的基石:函数闭包相关推荐
- 【Groovy】Groovy 动态语言特性 ( Groovy 中函数实参自动类型推断 | 函数动态参数注意事项 )
文章目录 前言 一.Groovy 中函数实参自动类型推断 二.函数动态参数注意事项 三.完整代码示例 前言 Groovy 是动态语言 , Java 是静态语言 ; 本篇博客讨论 Groovy 中 , ...
- 【C 语言】动态库封装与设计 ( 动态库调用环境搭建 | 创建应用 | 拷贝动态库相关文件到源码路径 | 导入头文件 | 配置动态库引用 | 调用动态库中的函数 )
文章目录 一.在 Visual Studio 2019 中创建 " 控制台应用 " 程序 二.拷贝 xxx.lib.xxx.dll.xxx.h 到源码路径 三.导入 xxx.h 头 ...
- c语言malloc用法 数组,详解C语言用malloc函数申请二维动态数组的实例
详解C语言用malloc函数申请二维动态数组的实例 C语言在程序运行中动态的申请及释放内存十分方便,一维数组的申请及释放比较简单. Sample one #include int main() { c ...
- C语言调用Go生成的动态库中的函数
工作中遇到的Go语言调用C函数的场景比较多,之前也写过一篇<cgo中将C函数返回的数组转为Go中的slice>. 目前在开发OpenSIPS的过程中,有些功能用C写起来麻烦,故第一次尝试了 ...
- 动态语言的灵活性是把双刃剑 -- 以Python语言为例
本文有些零碎,总题来说,包括两个问题: (1)可变对象(最常见的是list dict)被意外修改的问题, (2)对参数(parameter)的检查问题. 这两个问题,本质都是因为动态语言(动态类型语言 ...
- 高并发大流量专题---8、动态语言的并发处理
高并发大流量专题---8.动态语言的并发处理 一.总结 一句话总结: 和本科毕业论文连起来了:基于消息中间件Rocket MQ的研究:用于并发处理的消息队列 1.什么是进程.线程.协程? 进程(Pro ...
- 为什么php动态语言,动态语言静态化
[TOC] ## 什么是动态语言静态化 将现有PHP等动态语言的逻辑代码生成为静态HTML文件,用户访问动态脚本重定向到静态HTML文件的过程. 对实时性要求不高的页面 ## 为什么要静态化 动态脚本 ...
- 为什么说Python是一门动态语言--Python的魅力
动态语言的定义:动态编程语言是高级程序设计语言的一个类别,在计算机科学领域已被广泛应用. 它是一类在执行时能够改变其结构的语言:比如新的函数.对象.甚至代码能够被引进,已有的函数能够被删除或是其它结构 ...
- 为什么可以说Java语言是准动态语言?
什么是动态语言? 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如JavaScript便是一个典型的动态语言. 除此之外如Ruby.Python ...
最新文章
- linux安装oracle常见错误 总结
- GIT 团队协作快速入门使用
- 【鬼网络】之DHCP原理与配置
- 成长 | 《大厂晋升指南》学习总结(上)
- 【PhotoScan精品教程】任务一:新建工程、导入照片、设置坐标系、导入控制点(POS)、自由空三
- 数据透视表和数据交叉表_数据透视表的数据提取
- mac11.14 mysql_mysql 5.7 11 章 数据类型(1)
- 函数头文件php_PHP 7.4 的 FFI 将支持更好地在 PHP 中使用 C 函数/数据结构
- loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)
- 【经典】Noip动态规划
- Win10人脉应用将关闭与新浪微博关联
- fiddler响应中文乱码问题
- 202102 sqlplus command not found 注意切换用户
- bzoj1005 [HNOI2008]明明的烦恼(Prufer数列+高精度(wys算法。。。))
- 动手打造N合1操作系统安装光盘
- pytorch蜜蜂蚂蚁数据集处理python代码
- 天道酬勤,记春招之路(完美世界,360,腾讯IEG,网易雷火)
- Stale branches 设置_手机资讯:iPhone 如何设置来电闪光灯苹果手机 LED 灯来电提醒设置教程...
- python 安装dmPython
- 谜样的计算机科学之父
热门文章
- MySql安装及Navicat连接(解决Starting the server失败;mysql输入密码登录报错1045(28000),不输入密码却能登录;Navicat连接报错2059)
- 弗吉尼亚理工计算机科学排名,2020年弗吉尼亚理工大学排名TFE Times美国最佳计算机科学硕士专业排名第45...
- 循环码差错图样matlab,基于MATLAB的(15,7)循环码的编译仿真.doc
- ef mysql dbfirst,.NetCore教程之 EFCore連接Mysql DBFirst模式
- UE4学习-使用蓝图进行一个关卡的设计
- ajax怎么在html与php中使用,如何使用ajax和php将数据从数据库表放到html表
- 深度探索linux系统虚拟化 原理与实现,深度探索Linux系统虚拟化:原理与实现
- postgres xshell copy 命令 内存溢出_良心国产工具,比Xshell好用还免费!
- “搬砖”机器人,每小时800块!
- 史上卖得最多的芯片......原来是这个!