Область видимости
Область видимости является вторым следствием вложенности объектов. Область видимости означает что-то вроде "контекста", в том смысле, "что именно можно увидеть/понять с разных точек/мест". Возвращаясь опять к метафоре с младенцем, младенец может видеть "внутри" своей матери (с фонариком), но не может видеть видеть то, что видит мама. В ActionScript вы можете автоматически делать ссылку на область видимости объекта, в первую очередь, ActionScript будет искать свойства в собственной области видимости объекта.
Из всех характеристик контейнеров, которые нас больше всего интересуют, наиболее полезной является не их картонность, а их "контейнеробильность" (эдакое вот словечко в стиле Дж. Буша). В контейнеры можно помещать все, что угодно, включая другие контейнеры. Изнутри контейнера, можно видеть только те предметы, которые находятся в нем, но никак не те, что снаружи. И, хотя вы можете видеть другие контейнеры в вашей области видимости, заглянуть внутрь них вам не удастся. Рассмотрим несложный пример. Давайте создадим еще один объект personA:
personA= { name : "Ann", favs : { site1 : "flash.com", test1 : function(){ trace (this.site1) }, test2 : function(){ trace (this.name ) } }, test3: function(){ trace (this.name ) }, test4: function(){ trace (this.site1) } }; personA.favs.test1(); // flash.com personA.favs.test2(); // null (ребеной не может видеть родителя) personA.test3(); // Ann personA.test4(); // null (родитель не может видеть внутри ребенка)
В этом примере, ключевое слово this означает "контейнер, вызвавший эту функцию", что по счастью означает именно тот контейнер, который мы пытаемся увидеть внутри. На данном этапе, совершенно необязательно разбираться в том, как это работает, достаточно на простом языке описать, что будет на выходе каждого свойства test.
test1: Свойство, называемое site1 в контейнере personA.favs. // которое имеет значение "flash.com"
test2: Свойство, называемое name в контейнере personA.favs. // нет такого свойства в personA.favs
test3: Свойство, называемое name в контейнере personA. // которое имеет значение "Ann"
test4: Свойство, называемое site1 в контейнере personA. // нет такого свойства в personA
Интересно, что будет, если мы изменим test4 следующим образом:
test4: function(){return this.favs.site1;} // Обратите внимание на '.favs.'
Отлично, работает. Что же на выходе?
test4: Свойство, называемое site1, в контейнере, называемом favs, который находится в данном контейнере. // ? попробуйте найти значение, используя новый test4 код...
При использовании первого объекта A существует ряд ограничений. Главная задача этого объекта - дать имя блоку функций, чтобы его можно было вызвать. После этого можете использовать его именное пространство для хранения информации о самой функции. Такой информацией может быть, например, имя класса объекта (которое может понадобиться для исправления ошибок), или счётчик, который следит за количеством экземпляров, вызванных с помощью объекта. Такие свойства никак не повлияют на работу функции. В последующих экземплярах от них не останется и следа.
Второй объект, объект активации, производит самопостроение в процессе создания экземпляра. Он бывает совершенно необходим. У него свои границы действия, а его собственное ключевое слово this присваивается контейнеру, в котором он может создавать или изменять свойства. И это только часть его возможностей в создании экземпляра, самый распространённый, но вовсе не самый значимый случай его использования. У нас будет возможность убедиться в этом, когда мы начнём разбираться с прототипами.
Идея создания вызываемого блока инструкций, принадлежащего функции, вновь напоминает нам о Flash. Помните? Символ в библиотеке имеет информацию, которая сообщается экземплярам, управляя их поведением и видом. А как насчёт другой части функции, объекта A в предыдущем примере? Эта часть используется для хранения информации об объекте не относящейся к экземплярам. Например, все символы в библиотеке имеют имена, но эти имена не присваиваются (и вообще никак не относятся) к экземплярам. Если включить опцию "Update Use Count" в библиотеке, каждый символ будет показывать, сколько раз он используется в вашем клипе. Вот и получается, что это свойство имеет отношение к классу, но не имеет отношения к экземпляру. Самое логичное было бы помещать такую информацию вместе с объектом класса. В ActionScript предусмотрена возможность доступа к такой информации (используя intance.constructor.temp, - мы к этому ещё вернёмся), тогда как во Flash она недоступна для ваших экземпляров (она доступна только вам, как пользователю). Конечно, у вас не так уж и часто возникает необходимость в использовании именного пространства, но иногда это просто необходимо.
<<
ООП во Flash 5 >>