Особенности цепочки областей видимости функций

Прежде чем приступить к описанию тонкостей цепочки областей видимости функций, вспомним, что означает этот термин в ActionScript. Цепочка областей видимости (scope chain) — это последовательность объектов, которые интерпретатор просматривает при обращении к идентификатору.

Цепочка областей видимости является атрибутом исполнимого кода и представляет собой одно из проявлений концепции наследования.

В ActionScript исполнимый код бывает двух типов: основной код (или код временной диаграммы) и код функций. Официально считается, что цепочка областей видимости для кода временной диаграммы образована двумя звеньями: сама временная диаграмма и объект Global. Но так как клип инаследует свойства прототипа конструктора MovieClip и прототипа конструктора Object, то впол-не можно утверждать, что цепочка областей видимости его кода состоит из 4 звеньев. При создании функции в качестве основы ее цепочки областей видимости копируется цепочка того исполнимого кода, в котором находится ее определение. При вызове функции в конец записанной в ее специальном внутреннем свойстве цепочки областей видимости добавляется новое звено — адрес объекта активации (в частности, это позволяет создавать локальные переменные функций).


Итоговый список объектов используется в качестве цепочки областей видимости при выполнении кода функции. Таким образом, длина цепочки областей видимости для функций составляет целых 5 звеньев. В случае же, если определение функции находится в коде другой функции или же если используется предложение with(), то присущая ей цепочка областей видимости может состоять из 6 и более звеньев, Из описанных выше особенностей задания цепочки областей видимости для кода функции можно вывести несколько важных следствий:

• Присвоение функции одной временной диаграммы переменной другой не означает, что при вызове ее через данную переменную исходная цепочка областей видимости будет заменена цепочкой, характерной для переменной. Подобная схема была характерна для Flash 5, что было весьма неудобно и, кроме того, не соответствовало ЕСМА-262. Во Flash MX 2004 цепочка областей видимости функции остается неизменной независимо от того, откуда она вызывается.

• Для того чтобы создать метод объекта, зачастую недостаточно присвоить функцию его свойству (или свойству одного из прототипов его цепочки наследования). Так как при этом цепочка областей видимости ее кода не изменится, то вызвавший ее объект будет просто из него не «виден*.


А это означает, что обратиться напрямую к методам и свойствам объекта-хозяина из кода нового метода невозможно, Пример:

// mov — клип, расположенный на _root
function sizer() :Void {
_xscale = 200;
_yscale = 200;
mov.sizer=sizer; // Делаем функцию sizer() методом клипа mov
mov.sizer(); // Происходит увеличение _root: на ней определена
// функция sizer()

В приведенном коде ошибка обусловлена игнорированием того факта, что при присвоении функции свойству объекта ее цепочка областей видимости не меняется. Поэтому при вызове метода sizer() клипом mov произошло изменение не его свойств _xscale и _yscale, а аналогичных свойств, но основной временной диаграммы, на которой располагается определение функции sizer(). Обойти же описанную проблему можно, использовав указатель this. Данный указатель всегда ссылается на объект, который вызвал метод, вне зависимости от того, где расположено определение соответствующей функции:

function sizer():Void {
this._xscale = 200; // Используем указатель this
this._yscale = 200;
}
MovieClip.prototype.sizer=sizer;
mov.sizer(); // Происходит увеличение непосредственно клипа mov

• Если функция задана в теле другой функции, то в качестве основы ее цепочки областей видимости используется цепочка областей видимости кода функции-хозяйки.


Это означает, что из кода вложенной функции будут доступны локальные переменные функции внешней:

function funс():Void {
var per:String = "Привет"; // Создаем локальную переменную
function func2():Void {
// Пробуем из вложенной функции вызвать переменную per
trace(per); // Выводит: Привет
}
func2();}
func();

Если необходимо получить доступ к локальным переменным внешней функции, одноименные которым локальные переменные имеются и в коде функции вложенной (или нужно прочитать значение одного из служебных свойств объекта активации внешней функции), то нужно использовать указатель this.

• Если функция определена в основном коде, а ее вызов происходит из другой функции, то, в противоположность предыдущему случаю, ее объект активации в цепочку областей видимости кода вызываемой функции включен не будет (объясните, почему):

function func():Void {
var per:Number = "Привет";
func2();
}
function func2():Void {
trace(per); // Выводит: undefined
}
func();

Методы, создаваемые на основании определений во внешних классах, имеют цепочку областей видимости, радикально отличающуюся от цепочки областей видимости обычной функции.


Во-первых, она динамична — в нее входит объект, вызвавший метод. Во-вторых, она образована всего 3 звеньями — объектом активации, объектом, вызвавшим метод, и объектом Globa.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Action Script на эту тему:
Предложение return
Функции как объекты

Вернуться в раздел: Action Script / 4. Функции