【问题标题】:AS3 Dynamic Class Dynamic Method NamesAS3 动态类动态方法名称
【发布时间】:2009-09-10 21:41:28
【问题描述】:

我显然在这里遗漏了一些东西。

我需要从数组中填充动态 AS3 类的方法(参见下面的愚蠢示例)。

但是当我调用这些方法时,它们似乎都是同一个方法。在下面的例子中,所有的方法都是foobar1

如果我手动创建方法,没有循环,一切都很好。

有什么线索吗?

  package foo
  {
    public class Bar
    {
      public function testDynamicClassSanity():void
      {
        var foo:Foo = new Foo();
        var methods:Object = { foobar1: 101, foobar2: 201, foobar3: 301 };

        for (var key:String in methods)
        {
          var val:Number = methods[key];
          foo[key] = function():Number
          {
            return val;
          };
        }

        // Next trace prints
        // 101 = 101 201 = 101 301 = 101
        trace(
            101, "=", foo.foobar1(),
            201, "=", foo.foobar2(),
            301, "=", foo.foobar3()
          );
      }
    }
  }

  internal dynamic class Foo
  {
  };

【问题讨论】:

    标签: actionscript-3 dynamic-class


    【解决方案1】:

    我猜问题出在val 的范围内——你假设它的范围是 for 循环,但在 AS3 中并非如此,范围是函数。你所有的电话都返回 301,我是否正确?

    更新:由于解决您遇到的问题(变量val 被引用并且稍后才被解决而不是被“复制”到您的函数中)非常麻烦:根据您的用例,您可以检查该方法调用并使用Proxy 提供的功能在表中查找所需的结果。

    【讨论】:

    • 是的,你是对的(几乎是 101)。我已经更新了这个问题。那么如何解决这个问题呢?
    • 啊,我假设 for 循环会按照定义的顺序遍历对象的属性,这当然是愚蠢的假设 :-) 检查另一个问题 stackoverflow.com/questions/422784/…提示。
    【解决方案2】:

    我认为您的问题是 var 变量的范围。试试这个修改:

    for (var key:String in methods)
    {
      var val:Number = methods[key];
      foo[key] = function (valInternal:Number) {
        return function():Number
        {
            return valInternal;
        };
      }(val);
    }
    

    (上述技巧适用于 Javascript 以解决类似问题...我敢打赌它适用于 AS3)

    【讨论】:

      【解决方案3】:

      为了记录,我将在此处发布testDynamicClassSanity() 函数的更正版本:

          public function testDynamicClassSanity():void
          {
            var foo:Foo = new Foo();
            var methods:Object = { foobar1: 101, foobar2: 201, foobar3: 301 };
      
            // We have to introduce new scope
            var makeCallback:Function = function(result:Number):Function
            {
              return function():Number
              {
                return result;
              }
            }
      
            for (var key:String in methods)
            {
              foo[key] = makeCallback(methods[key])
            }
      
            // Prints as intended
            // 101 = 101 201 = 201 301 = 301
            trace(
                101, "=", foo.foobar1(),
                201, "=", foo.foobar2(),
                301, "=", foo.foobar3()
              );
           }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-22
        • 2021-02-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多