Метод Callee
Внутри активированного конструктора, вам автоматически предоставляется доступ к двум объектам. Именно там, в области видимости активированного объекта, исполняются команды. Код также включает ссылку на второй экземпляр, созданный ключевым словом this, (по природе Flash'a, вам также предоставляется доступ к _root линейке - его можно спокойно проигнорировать). Этим обычно и исчерпываются ваши потребности. Однако, чего здесь не хватает, так это ссылки на задействованный класс. Сначала вам может показаться, что она присутствует в текущей области видимости, но помните, что эта область является отдельным временным активированным объектом и соответственно, все, что создано в этой области будет удалено как только она прекратит работу. Очевидно, что это - не класс. Можно попытаться найти его через ключевое слово this (this.constructor или this.__proto__). Хотя this является временным и безымянным контейнером, которому еще только предстоит стать экземпляром, его свойства constructor и __proto__ уже известны и заранее заданы. Таким образом, this.constructor указывает на class, а this.__proto__ указывает на class.prototype. Следует помнить, однако, что это - указание на тот class (или class.prototype), который создал данный экземпляр. Таким образом, если вы пользуетесь наследованием и одновременно используете множественные уровни конструкторов, вам понадобится кое-что еще.
К счастью, эта проблема решается использованием arguments.callee. К несчастью, это недокументированная функция и это влечет за собой все, что с такими ситуациями обычно связано. Возможно, вам будет проще избежать необходимости вызова callee путем изменения логики вашей программы. Как бы то ни было, она остается очень полезным инструментом при тестировании различных объектно-ориентированных структур, которых вы наверняка будете создавать сотнями. Она также является очень полезным инструментом отладки. На что же именно она указывает?
Arguments.callee указывает на функцию (да, класс или метод) к которому прикреплен текущий активированный объект. Таким образом, для того, чтобы конструктор нашел свой класс, в качестве пути достаточно просто указать arguments.callee. Это будет работать всегда, независимо от того, насколько далеко конструктор находится от экземпляра. Далее обычно каждому классу присваивается имя (например, Dog.name="Dog") и для определения того, какой конструктор работает в каком классе применяется команда (из активированного объекта Dog).
trace( arguments.callee.name );
Это может быть очень полезно для отладки. Нахождение прототипа класса изнутри активированного объекта тоже не представляет трудности - arguments.callee.prototype. Arguments.callee также показывает метод, которым можно найти имя его метода, опять-таки простым использованием arguments.callee. Это не так полезно, поскольку свойства у методов обычно не прикрепляются ни к объекту с именем метода, ни к объекту прототипа, поэтому ссылки на эти объекты обычно не требуется. Кроме того, не существует надежного способа, которым метод находил бы объект с именем класса, к которому он принадлежит (за исключением прописывания ссылки вручную), что значительно ограничивает полезность применения arguments.callee в конструкторе. (Получить имя класса метода изнутри метода можно с использованием this.__proto__.constructor.x или, если наследование имеет два уровня глубины, с использованием this.__proto__.__proto__.constructor.x, но при этом у вас нет возможности убедиться в том, сколько уровней глубины имеет ваш метод.)
Ниже приводится пример кода для экспериментирования. Вероятно, callee покажется вам наиболее полезной при проверке структур и отладке.
Class = function() { // найти класс из конструктора trace( "Class: " + arguments.callee.x ); // Вывод: Class: объект с именем класса
// найти прототип класса из конструктора trace( "Class.prototype: " + arguments.callee.prototype.x); // Вывод: Class.prototype: прототип класса }
Class.x = "Class name object"; Class.prototype.x = "Class prototype";
Class.prototype.method = function() { // найти имя метода из внутреннего метода trace("method: " + arguments.callee.x); // Вывод: method: объект с именем метода
// найти статические свойства класса из метода trace("method: " + this.__proto__.constructor.x); // (работает, только если класс на один уровень выше экземпляра) } Class.prototype.method.x = "method name Object";
aa = new Class(); // Конструктор теста aa.method(); // Метод теста
<<
ООП во Flash 5 >>