10. Подключение JavaScript к гипертекстовой странице
Глобальные переменные и функции
|
Уже отмечалось (см., например, Заметка 5. Переменные), что код JavaScript выполняется в контексте глобального объекта, и таким объектом является объект window (описывает окно браузера), если мы программируем для браузера. Это означает, что все глобальные переменные становятся свойствами объекта window. Можно было бы и не говорить дополнительно о функциях, так как функции JavaScript мало чем отличаются от переменных, но все же скажем: глобальные функции становятся методами объекта window. |
Замечание 1. Вспомним, что «метод» — это условное название свойства объекта в том случае, когда значением свойства является функция.
Замечание 2. Вспомним и то, что слова «значением свойства является функция», означают на самом деле, что значением свойства является ссылка на функцию, которую интерпретатор JavaScript располагает где-то в памяти. Свойство или переменная содержат сами значения только для данных элементарного типа. В случае объекта (а функция — это объект) переменные и свойства хранят ссылки на него, а сам объект располагается где-то в памяти.
Так, если мы записываем код:
function kv(t) { return t*t;}
var x = kv(10); // 100
то тем самым добавляем в объект window два свойства с именами x и kv.
К переменной x можно обращаться, как свойству window.x, а к функции kv, как к методу window.kv.
Такое поведение среды, в которой работает код, таит в себе реальную опасность — можно случайно перекрыть (переопределить) встроенное свойство или метод объекта window.
Чтобы избежать подобной неприятности, программисты стараются не использовать в своем коде более одного глобального имени, а то и вовсе обходятся без глобальных имен.
Как обойтись одним глобальным именем
var objRobotland = {}; // Объявление единственного глобального имени
objRobotland.kv = function (t) { return t*t;}
objRobotland.x = objRobotland.kv(10);
В этом коде задействовано только одно глобальное имя — objRobotland. Это имя созданного объекта. Все переменные и функции описываются как его свойства и методы.
Для построения уникального глобального имени можно задействовать адрес электронной почты (или домен) автора:
var objRobotlandPereslavlRu = {};
objRobotlandPereslavlRu.kv = function (t) { return t*t;}
objRobotlandPereslavlRu.x = objRobotlandPereslavlRu.kv(10);
Такая конструкция позволит, практически на 100%, избежать совпадения построенного идентификатора с глобальными именами сторонних кодов, если мы собираемся их использовать на наших страницах. И позволит без конфликтов задействовать наши коды другими программистами.
Если мы не собираемся писать (и использовать) публичные коды, то можно, конечно, обойтись и более короткими идентификаторами:
var objRobot = {};
objRobot.kv = function (t) { return t*t;}
objRobot.x = objRobot.kv(10);
Как обойтись без глобальных имен
Если код должен быть выполнен только один раз, можно поместить его внутрь функционального литерала (безымянной функции) и вызвать функциональный литерал на исполнение:
(function ()
{
var kv = function (t) { return t*t;}
var x = kv(10);
alert(x); // 100
})();
alert(x); // Сообщение об ошибке
Здесь x и kv — это локальные переменные, а глобальной переменной нет ни одной.
Функция alert, которую мы уже много раз использовали при отладке своих кодов, является встроенным методом объекта window, то есть более точное написание этой функции — window.alert. Но в написании свойств и методов глобального объекта его имя можно опускать, поэтому мы записываем вызов этого метода более кратко: alert.
Часто приходится выполнять какие-то действия над объектами страницы. Это правомочно лишь после того, как браузер страницу построит. Значит, код должен начинать работу не сразу, а только после наступления события onload.
Можно, в качестве обработчика события onload, написать функциональный литерал, и в нём выполнить всё необходимое:
window.onload = function () // Объекту window назначен обработчик
{ // события onload -- функциональный литерал
var kv = function (t) { return t*t;}
var x = kv(10);
alert(x); // 100
};
Замечание 1. При наступлении события браузер выполняет функцию-обработчик, ссылку на которую содержит соответствующее свойство объекта, построенного для элемента, на котором событие возникло. Так, после загрузки документа в окно, браузер выполняет функцию, заданную свойством window.onload. Таким образом, если нужно что-то сделать после полной загрузки документа, поместите действия в некую функцию f и присвойте ссылку на нее свойству window.onload: window.onload = f. Можно не именовать функцию, а задать ее функциональным литералом в правой части равенства: window.onload = function(){...};. Именно так и сделано в приведённом выше примере.
Замечание 2. Можно было бы вместо window.onload записывать просто onload, но такая запись смотрелась бы «подозрительно», словно onload — это наша собственная глобальная переменная, а не встроенное свойство глобального объекта.
Замечание 3. Обработчик события onload можно задавать и как значение одноименного атрибута в открывающем теге элемента BODY: <BODY onload="...">.
Функциональный литерал будет вызван на исполнение после наступления события onload, то есть после того, как браузер построит объектную модель документа и покажет его в своем окне.