AS3 Dynamic Class Имена динамических методов - PullRequest
0 голосов
/ 11 сентября 2009

Я явно что-то здесь упускаю.

Мне нужно заполнить методы динамического класса 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
  {
  };

Ответы [ 3 ]

4 голосов
/ 11 сентября 2009

Я полагаю, что проблема в области видимости val - вы предполагаете, что его область действия - это цикл for, но в AS3 это не так, область действия - это функция. Я прав, что все ваши звонки возвращают 301?

Обновление: поскольку обойти проблему, с которой вы столкнулись (переменная val ссылается и только потом решается вместо того, чтобы «копироваться» в вашу функцию), довольно громоздка: в зависимости от варианта использования вы можете проверить метод звонки и просто найдите желаемый результат в таблице, используя функции, предоставляемые Proxy .

2 голосов
/ 11 сентября 2009

Я думаю, что ваша проблема в определении области действия переменной 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)

1 голос
/ 11 сентября 2009

Для записей я выложу здесь исправленную версию функции 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()
        );
     }
...