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, то есть после того, как браузер построит объектную модель документа и покажет его в своем окне.