9RIA.com天地会 - 论坛

返回列表 发帖

天地培训

9RIA天地会官方培训机构

Adobe官方认证培训中心

[新闻资讯] [业界动态] AS3 函数闭包

  • 资讯类型:
  • 来源页面:
  • 资讯原标题:
  • 资讯原作者:
  • 我的评论:
    对这篇文你有啥看法,跟贴说说吧!欢迎口水和板砖,哈哈。欢迎大家和我们一同分享更多资讯。

    闭包是可以包含自由(未绑定)变量的代码块; 这些变量不是在这个代码块或者任何全局上下文中定义的,而是在定义代码块的环境中定义。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量的存在,相关变量引用没有释放)和为自由变量提供绑定的计算环境(作用域)。在 Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby 和 Python 等语言中都能找到对闭包不同程度的支持。   
    闭包的价值在于可以作为函数对象 或者匿名函数,对于类型系统而言这就意味着不仅要表示数据还要表示代码。支持闭包的多数语言都将函数作为第一级对象,就是说这些函数可以存储到变量中、作为参数传递给其他函数,最重要的是能够被函数动态地创建和返回。

    package  
    {
        import flash.display.Sprite;
       
        /**
         * ...
         * @author http://ria.args.cn ...
         */
        public class Test  extends Sprite
        {
            
            private var array:Array = new Array();
            public function Test()
            {
                for (var i:int = 0; i < 5; i++) {
                    var object:Object = new Object();
                    object.num = function():void {
                        this.number = i;
                        trace(this.number);
                    }
                    array.push(object);
                }

            }
            public function run():void {
                
                
                for (var i:int = 0; i < array.length; i++) {               
                    array.num();
                }
            }
        }
       
    }

    package  
    {
        import flash.display.Sprite;
       
        /**
         * ...
         * @author http://ria.args.cn  ...
         */
        public class RunTest  extends Sprite
        {
            
            public function RunTest()
            {
                var t:Test = new Test();
                t.run();
            }
            
        }
       
    }


    先调用 setup 方法,在 setup 方法的 for 语句中循环创建对象 obj,并为 obj 创建一个方法 num(),该方法将当前循环的 index 赋值给 obj 的一个属性 n,并 trace 出 n 的值。将 for 循环生成的对象存到数组 array 中用于在 run 方法中取出。 调用 run 方法,取出 array 中的对象,并调用他们的 num() 方法。 猜猜输出的结果是什么?

    结果是: 5 5 5 5 5 并不是期望中的(我期望中的): 0 1 2 3 4

    为什么呢? 研究并实验了几下才发现,原来函数闭包虽然可以记录上下文环境的 snapshot ,但却是最近状态的一个 snapshot ,比如上例在 for 循环中,虽然把循环的当前的 i 值赋给了 n ,然而 i 是属于 num() 函数之外的,是 snapshot 中的变量,所以它只记录最近的状态,也就是 for 循环的最后一次,i 等于 5  。输出的就都是 5 了。按照这个原理,你也可以实验一下,把 i 的最后状态改成其他的值,比如

    public function setup():void
    {     
      for(var i:int=0;i<5;i++)
      {         
        var obj:Object = {}         
        obj.num = function():void
        {            
           this.n = i            
           trace(this.n)         
        }         
        array.push(obj)     
      }     
      i = 100
    }

    虽然在 for 循环结束之后才设置的值,不过 i 依然在那个 snapshot 的范围之内,所以输出将会是 5 个 100 。

    既然知道了原理,问题解决起来就容易了。只要让 i 不在函数闭包的上下文环境的 snapshot 的范围里就好了。可以这样改写一下:




    public var array:Array = []  
    public function setup():void{   
      for(var i:int=0;i<5;i++)
      {      
      array.push(createObj(i))   
      }
    }  
    public function run():void
    {   
          for(var j:int=0;j<5;j++)
          {   
           array[j].num()     
          }
    }
    public function createObj(index:int):Object
    {
         var obj:Object = {}     
         obj.num = function():void
         {   
               this.n = index        
               trace(this.n)   
         }
         return obj
    }
    将创建函数闭包的部分拿到 createObj() 方法中,这样这个 snapshot 只是该函数的上下文环境,不会受到 i 的重复赋值的影响,输出结果也是预期的 0 1 2 3 4
    1

    评分人数

    值班管理员 赐本贴 威望 + 1 银子 + 20  诏曰:

    天地人才库
    还真没注意过~~,学习了
    www.xiaozhanchang.com
    小战场---打造属于flash的专业小游戏对战平台

    TOP

    建议楼主将代码 放到代码块中,并且不要用斜体。这篇文章很好!!
    红花漫天,天地威武!

    TOP

    好兄弟,讲义气!---by eko

    踏上天地会荣耀之路!

     

    申请舵主

    加入掘金队

    加入译林军

    知识专题整理

     

    咨询(QQ):

    1442604479(小地)

     

    为什么要用闭包呢?!!没看到什么特别的好处!!
    欢迎来小博浇水:http://blog.sina.com.cn/ladeng6666
    ----------------------------------
    我的qq群:43806024
    ----------------------------------

    TOP

    虽然没怎么明白,但还是学习了,继续明白中~~

    TOP

    为什么要用闭包呢?!!没看到什么特别的好处!!


    同感
    Flash AS3 游戏开发峰会(超级500人QQ群):35507613

    PV3D/Away3D  Flash3D 研究所:5926437X(不公开)

    TOP

    闭包。。让我想到了LUA。。

    TOP

    为什么要用闭包呢?!!没看到什么特别的好处!!
    ladeng6666 发表于 2010-1-29 22:42



        同問

    TOP

    感觉怎么写的 多了

    TOP

    感觉没啥用滴
    qq86868007

    TOP

    函数闭包,在JS里可以十分灵活地使用,在AS里算是高级特性,可以尝试着使用。
    我的博客 据说能增加RP值 嘿嘿嘿
    piggyi.com

    TOP

    AS1就有函数闭包了,  为什么有函数闭包,因为那时不支持class创建对象.   用函数闭包来模拟面象对象.

    TOP

    这种方法在as2里经常用
    其实number可以在外面先赋值
                for (var i:int = 0; i < 5; i++) {
                    var object:Object = new Object();
                    object.number = i;
                    object.num = function():void {
                       //this.number = i;
                        trace(this.number);
                    }
                    array.push(object);
    十年技术一场空

    TOP

    收藏了,回头仔细研究。

    TOP

    真没什么用啊,兄弟

    TOP

    返回列表