Показать сообщение отдельно
Старый 13.02.2004, 01:47
Dagi вне форума Посмотреть профиль Отправить личное сообщение для Dagi Найти все сообщения от Dagi
  № 17  
Dagi

Регистрация: Oct 2002
Адрес: Минск,Беларусь
Сообщений: 107
Подробное описание глобальных переменных от меня:



В чистом объектно-ориентированном программировании не существует понятия “глобальная переменная”. Все переменные (в данном случае правильнее употреблять термин “свойство”) являются локальными и не видны дальше “родного” объекта. До выхода Flash MX в ActionScript также не имелось возможности создавать глобальные переменные. Она появилась с введением особого свойства _global.
Свойство _global представляет собой указатель на объект Global (мы будем называть его именно Global, так как такой термин используется в ECMA-262), который является носителем конструкторов встроенных классов, глобальных функций и “родных” объектов ActionScript. Сохранив в нем переменную, вы сделаете ее доступной для любого исполнимого кода фильма. Более того, ее можно будет “увидеть” и из других фильмов, подгруженных в проигрыватель. Указывать при этом ее точный “адрес” не нужно.
_global.new_var=”Global”; // Этот код добавляем на первый кадр _root
// На временной диаграмме вложенного в _root клипа вводим:
trace(new_var) // Выводит: Global
Создавая глобальную переменную, важно проследить, чтобы ее имя не совпало с именем ни одного из свойств объектов, относящихся к текущей цепочке областей видимости. Это связано с тем, что объект Global завершает цепочку областей видимости любого исполнимого кода, поэтому, вполне вероятно, что до глобальной переменной интерпретатор может и не добраться, найдя подходящий элемент и “поближе”. Так, если вы вызываете переменную из кода функции, расположенной на основной временной диаграмме, то вначале на ее наличие будет проверен относящийся к функции скрипт, затем – область _root, далее – прототип конструктора MovieClip, за ним – прототип конструктора Object, и лишь затем будет анализироваться объект Global:
_global.new_var="Привет"; // Этот код расположен на основной временной
// диаграмме
trace(new_var); // Выводит: Привет
// Создаем одноименное глобальной переменной свойство в одной из областей
// цепочки видимости
MovieClip.prototype.new_var="Пока";
trace(new_var); // Выводит: Пока (прототип MovieClip расположен
// “ближе” Global)
Переопределить глобальную переменную, указав только ее имя, невозможно. При этом будет создана новая локальная переменная. Для того чтобы изменить глобальную переменную, необходимо использовать ее полный “адрес”:
_global.prop = "Привет"; // Создаем глобальную переменную
prop = "Пока"; // Пробуем переопределить глобальную переменную
trace(prop); // Выводит: Пока (была создана локальная переменная)
trace(_global.prop); // Выводит: Привет (глобальная переменная изменена
// не была)
_global.prop="Пока"; // Переопределяем переменную по точному “адресу”
trace(_global.prop); // Выводит: Пока
Для глобальных переменных в ActionScript характерна двойственная природа. С одной стороны, они действительно во многом ведут себя, как переменные. Однако, фактически, они являются свойствами объекта Global, поэтому их вряд ли можно считать стопроцентными переменными. Наглядным же доказательством этого утверждения является то, что при создании глобальных переменных не используется ключевого слова var.
Во Flash 5 свойства _global не было. Однако создавать некоторое подобие глобальных переменных все же было возможно благодаря особенностям формирования цепочек областей видимости. Дело в том, что в цепочку областей видимости любого исполнимого кода, будь то код временной диаграммы или код функции, входит прототип конструктора Object (вернее, его свойства наследует входящий в цепочку областей видимости клип-носитель кода). Следовательно, любой исполнимый код наследует хранящиеся в нем компоненты. Благодаря этому, создав свойство прототипа класса Object, мы сможем добиться практически полной имитации глобальной переменной.
Вы можете спросить, если свойства объекта Global и прототипа конструктора Object в одинаковой степени обладают глобальной видимостью, то какая разница, какой путь использовать для эмуляции глобальных переменных. А разница имеется – и весьма существенная. Чтобы ее понять, разделим термины “глобальная переменная” и “глобальное свойство”. Глобальная переменная – это переменная, доступная для любого исполнимого кода. Глобальное свойство – это свойство, наследуемое объектами всех классов. Глобальная переменная сохраняется в объекте, находящемся в вершине цепочки областей видимости любого исполнимого кода - объекте Global. Глобальное свойство – это свойство прототипа, завершающего цепочку прототипов, присущую любому объекту. В ActionScript таким прототипом является прототип конструктора Object Разделение понятий “глобальная переменная” и “глобальное свойство” осложняется тем, что прототип конструктора Object входит как в любую цепочку прототипов, так и, косвенно, в любую цепочку областей видимости (что связано с тем, что код располагается на кадре временной диаграммы). По этой причине, его свойство будет доступно и в качестве переменной любого исполнимого кода, и как свойство любого объекта:
Object.prototype.new_var="Привет";
trace(new_var); // Выводит: Привет (new_var доступна для данного
// исполнимого кода)
trace([].new_var); // Выводит: Привет (new_var унаследовал класс Array)
Таким образом, свойство прототипа объекта Object можно одновременно рассматривать и как глобальную переменную, и как глобальное свойство. И это очень плохо, так как приводит к полнейшей путаницы в понятиях. Создавая глобальные переменные при помощи свойств объекта Global, вы хоть как-то сохраняете ту стройность языка, которую предусматривает ECMA-262, и которая была очень сильно нарушена при реализации ActionScript.