Расширение прототипа объекта в ActionScript 3

Всякий раз, когда я пытаюсь расширить прототип объекта, я получаю сообщение об ошибке:

Ошибка № 1056: не удается создать свойство my_extension для mx.core.UIComponentDescriptor.

Я поискал и нашел следующее:

Flash AS3: ReferenceError: Ошибка № 1056: невозможно создать свойство

ReferenceError: Ошибка № 1056 - ошибка имени экземпляра

Я использую не визуальную среду IDE для проектирования сцены, а файлы MXML и AS3, поэтому я не уверен, что делать с этой ошибкой.

Мой код:

Object.prototype.keys = function(): Array {
  var keys: Array = [];

  for (var key: * in this) {
    keys.push(key);
  }

  return keys;
}

Object.prototype.values = function(): Array {
  var values: Array = [];

  for each (var value: * in this) {
    values.push(value);
  }

  return values;
}

person Kevin Li    schedule 22.06.2012    source источник
comment
поместите код в фигурные скобки: object [keys] (); , потому что, если вы напишете без нединамического объекта, вы получите ошибку времени компиляции. В любом случае, я бы посоветовал Вам, например: создать класс ObjectUtil и внутри функцию getKeys, чем использовать ObjectUtil.getKeys (myObject);   -  person turbosqel    schedule 22.06.2012


Ответы (1)


Использование prototype для расширения класса похоже на ActionScript 1 или 2.

В AS3 вы можете создать прототип, если класс является динамическим.

У прототипа есть недостатки:

  • Расширять можно только динамические классы, например, нельзя добавлять методы в Math.
  • Вызовы методов, хранящихся в прототипе, выполняются дольше.
  • Поскольку методы добавляются во время выполнения, редакторы не могут отображать их с подсказками по коду или использовать правильную подсветку синтаксиса.

Поскольку все классы расширяют объект, нет необходимости явно объявлять Object в качестве базы; однако вы можете определить класс AbstractObject для расширения:

package
{

    public dynamic class AbstractObject extends Object
    {

        public function AbstractObject()
        {
            super();
        }

        public function get keys():Array
        {
            var keys:Array = [];

            for (var key:* in this)
            {
                keys.push(key);
            }

            return keys;
        }

        public function get values():Array
        {
            var values:Array = [];

            for each (var value:* in this)
            {
                values.push(value);
            }

            return values;
        }

    }
}

Подтип AbstractObject для ваших классов.

person Jason Sturges    schedule 22.06.2012
comment
Вам нужен объект extends? Я думал, каждый класс по умолчанию является объектом? - person Neil; 22.06.2012
comment
Нет, что я сказал в своем ответе. - person Jason Sturges; 22.06.2012
comment
Расширение объекта не сработает для моих целей. Я до сих пор не совсем понимаю - вы подразумеваете, что Object - это статический класс? - person Kevin Li; 22.06.2012
comment
Вместо того, чтобы создавать прототипы членов для определений классов, используйте объектно-ориентированные парадигмы разработки, расширяя базовый класс. В противном случае используйте некоторый статический класс ObjectUtil, как рекомендуется для этой функции. - person Jason Sturges; 23.06.2012
comment
Я +1 к этому замечательному ответу и плюс парень, задающий вопрос, вероятно, не примет никаких ответов. - person The_asMan; 23.06.2012
comment
Хотя я видел множество людей, упоминающих об этом, я никогда не встречал тестов, доказывающих, что добавление методов к прототипу нативного типа влияет на производительность. Я знаю, что Flash сначала ищет методы уровня класса, а затем методы прототипа, если в классе их нет, но в случае собственных типов не все методы в прототипе? Для справки я нашел эту короткую статью о расширении основных типов tobyho.com / 2009/05/02 / modifying-core-types-in - person Steve Mason; 06.05.2016
comment
Я хотел бы упомянуть, что меня сюда привело то, что я переписываю кучу методов Array, которые недавно были введены в JavaScript. От меня (к сожалению) требуется использовать ActionScript, потому что я работаю в сфере рекламных технологий и стараюсь использовать как можно больше последних достижений в ecmascript для улучшения своего кода. Помимо изменения прототипа или расширения собственных типов, вы также можете использовать call() в своем методе. Например, ArrayUtils.reduceRight.call([1,2,3], myReducerFn). - person Steve Mason; 06.05.2016
comment
@SteveMason Внутри AVM2 объект признаков оптимизирован с учетом деталей класса, уменьшая память и сокращая прямые машинные инструкции. Цепочки прототипов являются устаревшими, обеспечивая альтернативный механизм наследования и несут накладные расходы в строгом режиме, требующем проверки динамического типа. - person Jason Sturges; 07.05.2016