Структура JavaScript
У любого языка программирования есть свои правила работы. Есть свои типы для переменных и ключевые слова этого языка. То есть, все то, что отличает этот язык от остальных его собратьев. Но все современные языки программирования практически одинаковы в своей структуре.
Как, собственно, действует программа-сценарий, внедренная в Web-страницу? В этот сценарии мы задаем самые различные реакции Web-страницы на какие-либо действия пользователя. Например, на нажатия кнопок, перемещение курсора мыши, работу с клавиатурой и так далее. На самом деле обрабатываемых событий достаточно много.
Как только произошло одно из указанных нами событий, браузер должен будет выполнить некоторую последовательность действий. Эта последовательность описывается при помощи блока ключевых слов и выражений. Подобные блоки кода называют процедурами. Помимо процедур в качестве блоков кода оформляются также функции. Их отличие в том, что процедуры
просто проделывают некоторые действия, а функции возвращают некоторое значение. Например, установить какой-либо цвет шрифта для абзаца — это процедура, а вычислить синус числа, являющегося вертикальной координатой верхнего левого угла графического изображения, — это уже функция.
В языке JavaScript заранее определены некоторые простейшие процедуры. Предопределенные заранее процедуры называются операторами. Также введены наиболее распространенные функции, но они особого наименования не получили. Так и остались функциями.
Для того, чтобы нам оперировать какими-либо числами, строками и прочими объектами, используются переменные. Переменная — это просто контейнер для хранения какого-либо значения. При этом значение переменной мы в любой момент можем изменить. В JavaScript используется несколько различных типов переменных. Мы можем создавать переменные, содержащие числовые значения, строки и логические выражения. При этом явно обозначать эти типы не нужно. Интерпретатор программы сам правильно обработает их. Достаточно лишь присвоить переменной какое-либо значение.
Объявлять переменные мы можем в любом месте программы, но никто еще не отменял понятие "хорошего стиля программирования". Хороший стиль программирования предусматривает, что все переменные, используемые в процедуре или функции, будут объявлены в самом начале этой процедуры или функции. При этом следует использовать ключевое слово var. Строго говоря, оно не является обязательным. Но если у нас будут совпадать наименования переменных в различных процедурах, используемых совместно, то может возникнуть совпадение имен. Применение ключевого слова var позволяет браузеру правильно обрабатывать переменные в таких случаях.
Рассмотрим маленький пример.
var х=1;
var s="Строка";
var t=True;
В каждой строке мы объявляем одну переменную. Так как мы сразу присваиваем им некоторые значения, то переменные обретают соответствующий тип. Переменная х содержит число, переменная s — строку, а переменная t предназначена для хранения логических значений.
Числовые значения мы можем записывать в программе в десятичном виде, как целые, так и дробные. Также мы можем записывать числа в восьмеричной и шестнадцатеричной системе исчисления. Числа в восьмеричной записи должны начинаться с нуля, а в шестнадцатеричной — с сочетания Ох. Если перечисленных способов записи чисел нам не хватает, мы можем воспользоваться экспоненциальным способом записи числа.
Если нам необходимо присвоить переменной строковое значение, то это значение мы должны поместить между кавычками, двойными или одинарными. В качестве строки может быть использован и один символ.
Переменные логического типа обычно используются в операторах выбора. Логических значений, естественно, существует всего два: True— истина, и False —ложь.
Если же мы объявляем переменную, но не хотим сразу присваивать ей какого-либо конкретного значения, можно присвоить ей неопределенное значение обозначаемое ключевым словом null. Таким образом, объявление переменной без присваивания значения и типа выполняется при помощи следующего фрагмента кода:
varr-x=null;
При работе с языком JavaScript всегда следует помнить, что он, в отличие от HTML, чувствителен к регистру символов. И если в написании ключевого слова допустить хотя бы одну ошибку, то интерпретатор языка, встроенный в браузер, не сможет выполнить всю программу.
Также следует обратить внимание на, то что каждое действие программы заканчивается символом точки с запятой. При помощи этого символа мы отделяем операторы и процедуры друг от друга, что позволяет браузеру правильно обрабатывать программу.
Язык JavaScript является языком со слабой типизацией. Это означает, что любая переменная в процессе работы программы может изменить свой тип. Так, например, при помощи следующего фрагмента кода мы превращаем переменную строкового типа в число:
var x="100";
х-х+1;
В первой строке этого фрагмента мы объявили переменную с наименованием х, которой присвоили текстовое значение, состоящее из трех символов. Во второй строке мы к этому строковому значению прибавили число. В результате этого действия в переменной х стало находиться числовое значение равное ста однрму.
Необходимо отметить, что в наименованиях переменных мы можем использовать только символы латинского алфавита, цифры и подчеркивания. Начинаться наименование должно только с буквенного символа. Пробелы в наименованиях переменных использовать нельзя.
Естественно, JavaScript, являясь достаточно развитым языком программирования, позволяет использовать в программах не только единичные переменные, но и массивы. По сути дела, массивы являются объектами, но это их свойство скрыто так глубоко, что нам не стоит о нем задумываться. Достаточно знать, как объявлять массив и обращаться к его элементам.
В языке JavaScript мы можем не только объявлять массив, но и динамически менять его размеры по мере выполнения программы. Следовательно, под массив должен выделяться некий фрагмент адресного пространства памяти. Подобное выделение всегда производится при помощи ключевого слова new.
А при помощи ключевого слова Array мы указываем интерпретатору программы, что выделяется пространство именно под массив.
Поэтому типичное объявление массива выглядит следующим образом:
my_array= new Array!); my_array(9)=0;
Этой конструкцией мы объявляем массив с наименованием my_array. При этом мы во второй строке инициализируем один из элементов только что объявленного массива, присваивая ему нулевое значение. Интерпретатор будет считать этот элемент последним, и наш массив изначально будет содержать десять элементов, так как нумерация элементов массивов в JavaScript начинается с нуля. А для того, чтобы обратиться к какому-либо элементу, после наименования массива в скобках указать порядковый номер этого элемента, как это и показано в нашем примере.
Впрочем, если это необходимо, мы можем указать размер массива при его объявлении. Для этого надо после ключевого слова Array в скобках указать предполагаемое количество элементов массива. В этом случае объявление нашего массива из десяти элементов будет выглядеть следующим образом:
my_array= new Array(10);
Во всех наших примерах объявления переменных мы использовали знак равенства, который на самом деле является одним из основных операторов. Это оператор присваивания. С его помощью мы можем переменным присваивать некие значения. Всего в языке JavaScript^есть шесть операторов присваивания. Рассмотрим их.
- Оператор = осуществляет стандартное присваивание. Пример его применения мы уже видели.
- Оператор += осуществляет присваивание со сложением. Таким образом, выражение х+=у эквивалентно х=х+у.
- Оператор -= осуществляет присваивание с вычитанием. Таким образом, выражение х-=у эквивалентно х=х-у.
- Оператор *= позволяет производить присваивание с умножением. Выражение х*=у равносильно выражению х=х*у.
- Оператор /= производит присваивание с делением. Выражение х/=у равносильно выражению х=х/у.
- Оператор %= позволяет осуществлять присваивание остатка целочисленного деления. Таким образом, выражение х%=у эквивалентно х=х%у.
Естественно, язык JavaScript обладает достаточно обширным набором базовых операторов, выполняющих стандартные действия с переменными. Нам никак нельзя обойтись без их рассмотрения.
- Оператор + осуществляет сложение! 2+3 равно 5.
- Оператор — осуществляет вычитание. 3-2 равно 1.
- Оператор * осуществляет умножение. 2*3 равно 6.
- Оператор / осуществляет деление, 6/3 равно 2.
- Оператор % выделяет остаток от целочисленного деления. 9%4 равно 1.
- Унарный оператор ++ осуществляет операцию инкремента, т. е. увеличения на едонвду.13-и- равно 4.
- Унарный оператор -- производит декремент, т. е. уменьшение на единицу, 3-- равно 2.
- Оператор & эквивалентен оператору AND. Эти операторы производят операцию побитового "И". При этом числа, к которым применяется этот оператор, автоматически переводятся в двоичную систему, и к ним поразрядно применяется данная операция. 2&5 равно 0.
- Оператор | эквивалентен оператору OR. Эти операторы производят поразрядную операцию двоичного "ИЛИ". 2|5 равно 7.
- Оператор ^ эквивалентен оператору хок. Эти операторы производят операцию побитового сложения по модулю 2. 3^2 равно 1.
- Оператор « осуществляет побитовый сдвиг двоичного представления числа влево на один разряд. 2« равно 4.
- Оператор » осуществляет побитовый сдвиг двоичного представления числа вправо на один разряд. 2» равно 1.
- Оператор &s осуществляет операцию "И" для логических значений. True && False равно False.
- Оператор I I осуществляет операцию "ИЛИ" для логических значений.
- True I I False равно True.
- Оператор ! осуществляет операцию отрицания для логических значений.
- False paвно True.
Любая программа, и наши скрипты не. являются исключением, практически никогда не может действовать без неких управляющих конструкций, которые и позволяют реализовать логику программы.
К таким управляющим конструкциям относятся циклы, условные операторы и операторы-переключатели. Все они достаточно просты, и применение их не вызовет каких-либо затруднений.
Условный оператор позволяет выполнять некие действия в том случае, если выполняется заданное разработчиком условие. Приведем маленький пример.
if (х—2) х*=7;
Данный фрагмент Кода проверяет значение переменной х. Если это значение равно двум, то оно увеличивается в семь раз. Но умножение это будет производиться тогда и только тогда, когда значение переменной равно двум. Проверка логических условий, как мы видим, производится при помощи ключевого слова if.
Интуитивно конструкция условного оператора ясна, но на самом деле его использование может быть и не таким простым, как в приведенном только что примере. В том случае, если нам надо проверить несколько логических условий сразу, каждое условие заключается в скобки, и к ним применяются логические операторы, которые мы рассмотрели несколько ранее. Так, если нам необходимо проверить выполнение сразу двух условий, то наш пример будет выглядеть следующим образом:
if <x«2) S5 (у<0) х*=7;
В этом случае умножение происходит только тогда, когда переменная х равна двум, а значение переменной у меньше нуля.
Условия проверки могут задаваться я»бо при помощи переменных логического типа, либо при помощи операторов сравнения, список которых приведен в табл. 7.1.
Таблица 7.1. Операторы сравнения
Оператор | Значение |
== | Точное равенство |
!= | Неравенство |
> | Больше |
>= | Больше или равно |
< | Меньше |
<= | Меньше или равно |
При выполнении условия программа интерпретатор выполняет только одно действие. А что делать, если надо выполнить не один оператор, а несколько? В этом случае необходимо все эти операторы объединить в единый блок. Для этого достаточно заключить все операторы в фигурные скобки, Я как это показано в следующем примере:
if (х-=2) {х*-7; у-1};
Все рассмотренные нами примеры, применения условного оператора построены на допущении, что при выпонении некоторого условия необходимо лишь выполнить некий блок кода. Но может возникнуть ситуация, когда при выполнении условия мы должны выполнить один блок кода, а если условие не выполняется— другой. В этом случае наш оператор сравнения приобретет следующий вид:
if (х==2) {х*=7; у=1) . 1
else {у=х};
Естественно, каждый блок действий может при необходимости включать в себя и другие условные операторы. Подобным образом создаются процедуры обработки сразу нескольких условий.
Однако, если есть целый список условий, каждому из которых мы должны сопоставить некоторый программный блок, следует воспользоваться оператором-переключателем. Но в нем выполнение тех или иных команд увязываются со значением какой-либо переменной, и нельзя использовать логические условия и уж тем более их комбинации. Вот как выглядит типичный пример применения оператора-переключателя:
switch (х) { 1
case 1: {Блок, выполнявшей, если х=1) , т
case 2: (Блок/ выполняемый, если х=2) J
default: {Блок, выполняемый, во всех остальных случаях
}
Смысл действия данного оператора достаточно ясен, но есть один подводный камень. В том случае, если переменная, относительно который мы и выстраиваем весь блок, равна некоторому значению, которое мы указали в операторе, то будет выполнен весь код от начала выполнения до конца оператора switch, я То есть, в нашем примере, если значение переменной х равно единице, то сначала будет выполнен блок кода для этого значения, затем блок, выполнявмый, если значение переменной равно двум, а потом еще и блок, используемый для всех остальных значений. Чтобы избежать этого, следует в конец каждого Шока кода вставлять оператор break. Данный оператор принудительно выводит управления за пределы конструкции, в которой он использовался. С его использованием типичный пример использования оператора-переключателя выглядит приблизительно следующим образом:
switch (х) { I
case 1: (y=x*2+z; break} . I
case 2: {y=x*3+z; break} I
default: {y-0; z=0) .1
}
Как видно, в последнем блоке, который выполняется для случаев, не перечисленных в операторе явно, мы не использовали оператор break, так как это блок кода является последним, и после его выполнения управление все равно выйдет за пределы оператора-переключателя.
Достаточно часто при написании своих скриптов нам потребуется использовать циклические конструкции, когда один и тот же блок кода необходимо выполнить определенное количество раз или выполнят* его до тех пор, пока 'некоторое логическое условие истинно. Обычно при помощи подобных циклов производится обработка массивов однородных данных, О массивах мы узнаем немного позже, а сейчас рассмотрим вопросы применения циклов в качестве управляющих конструкций.
В JavaScript предусмотрено три вида циклов. Стандартный цикл, когда некоторый блок кода выполняется определенное количество раз, реализуется при помощи оператора for. Наиболее типичный пример его использования выглядит следующим образом:
suro=0;
for (i=0; i<10; i-н-)
if my_array(i)>0 then sum»=sum+my_array (i) ;
В этом примере мы при помощи цикла производим суммирование всех положительных элементов массива с наименованием my_array, содержащим десять элементов. Как видно, для оператора for мы указываем некоторую дополнительную информацию в скобках. В скобках мы обязательно должны использовать три оператора. Все они связаны с переменной, которая является счетчиком повторений цикла. В нашем случае мы использовали переменную с наименованием 1. Первый оператор предназначен для присваивания переменной-счетчику стартового значения. Второй оператор является логическим условием. Цикл будет выполняться до тех пор, пока это условие истинно. А третий оператор обычно устанавливает операцию, которая будет выполняться каждый раз при завершении очередного прохода тела цикла. Чаще всего это операция соответствующего изменения значения переменного счетчика. Так как в нашем случае отсчет идет от нуля до девяти включительно, то мы используем инкремент, т. е. за один проход тела цикла, значение нашей переменной-счетчика увеличивается на единицу.
В нашем примере тело цикла представляет собой всего один условный оператор. Но если необходимо будет использовать не один оператор, а несколько, то их придется объединить в единый блок, при помощи уже знакомых нам фигурных скобок.
Также следует отметить, что для экстренного выхода из цикла, когда он еще не должен был закончиться штатным образом, мы можем использовать оператор break, который, как мы помним, выводит управление за пределы текущей логической конструкции. А если нам необходимо при наступлении каких-либо условий пропустить один шаг цикла, но при этом все-таки продолжить его .выполнение, стоит воспользоваться оператором continue, который выводит управление за пределы текущего блока. Но при этом оно будет оставаться в действующей логической конструкции. Как мы уже говорили ранее, в JavaScript существует три вида циклов. Один из них мы уже рассмотрели. Теперь мы узнаем, как действует цикл с предусловием. Если мы попробуем при помощи этой управляющей конструкции воспроизвести пример действия предыдущего цикла, то получится следующий фрагмент кода:
sum=0; 1
i=0; I
while (i<10) 1
'{ if my^_array(i)>0 then sum»&um+«ty_array(i); I
i++;} I
Как видно, данный вариант цикла реализуется при помощи оператора while, в котором указывается логическое условие. До тех пор, пока это условие будет истинным, тело цикла будет повторяться. Видно, что стартовое
значение переменной-счетчика мы задаем самостоятельно. И позаботиться
об ее изменении тоже нужно самим.
Последняя вариация циклической управляющей конструкции — цикл с постусловием — реализуется также при помощи оператора while, но на этот < раз с ним вместе должен использоваться оператор do. И наш цикл приобретет следующий вид:
sum=0; !
i=0;
do { . '.
if my_array (i)>0 then suro5»sum-t;my_array{i) ;
i++;-} while (i<10);
Как и прежде, тело цикла будет выполняться раз за разом до тех пор, пока логическое условие, указанное в операторе while, будет оставаться истинным. Но в чем же тогда разница между циклами с предусловием и с постусловием? Дело в том, что в первом из этих циклов логическое условие проверяется перед прохождением тела, цикла, а во втором — после. Таким образом, даже если логическое условие еще до старта не является истинным, цикл с постусловием все равно будет выполнен как минимум один раз.
И на этом список управляющих логических конструкций заканчивается. Но нам их будет вполне достаточно для того, чтобы реализовать любые свои замыслы.
Для создания программ-скриптов нам необходимо уметь создавать свои функции. Мы уже говорили, что функции, по сути дела, это те же процедуры, толька возвращающие некое значение. Следует отметить, что в качестве своих блоков действий мы можем в JavaScript создавать только функции. Но так как функции являются просто более общим вариантом процедур, то это не будет ограничением.
Вся программа-скрипт составлена из различных функций. Каждая функция выполняется интерпретатором в тот момент, когда наступает некоторое активизирующее событие. О событиях мы поговорим позже, а сейчас посмотрим, как объявляются функция в языке JavaScript. Простейший пример объявления функции выглядит следующим образом:
function my_first_function (name)
{alert("Hello, world! My naffie is "+name); return("Your name is "+na»e);}
Итак, из приведенного примера видно, что функция объявляется при помощи ключевого слова function, затем указывается ее наименование, и в скобках перечисляются переменные, которые передаются этой функции для работы. После этого пишется сам код функции, обязательно заключенный в фигурные скобки. Наша функция выводит окно сообщения с указанным текстом при помощи оператора alert.
Мы уже говорили, что любая функция должна возвращать какое-либо значение, даже если мы в этом и не нуждаемся. Таково обязательное условие. Возврат некоего значения, осуществляется при помощи ключевого слова return, которое одновременно обозначает, что последовательность действий, заложенных в нашу функцию, закончилась.
Завершая ознакомление со структурой языка JavaScript следует рассмотреть возможность работы с переменными составных типов и объектами. Но для того, чтобы рассматривать их, следует все же узнать, что такое объекты, и в чем их отличие от составных переменных. На самом деле, что такое объект понять достаточно легко, но вот точно и просто объяснить, что это, собственно, такое, не в пример сложнее. Можно сказать, что объект — это некоторая сущность со своим набором свойств и списком действий, которые могут выполняться по отношению к ним. Подобные действия назыаются методами, и их набор и механизм действия специфичны для каждого объекта. Также для каждого объекта определен набор возможных событий. Иными словами, объект заключает в себе как переменные, так и возможные действия над ними, определяемые происходящими событиями.
В JavaScript отсутствует возможность создавать свои собственные объекты, мы можем лишь пользоваться уже готовыми- Все доступные нам объекты так или иначе работают с Web-страницей, в которую внедрена программа на языке JavaScript. Так, основным объектом является объект с наименованием window, который позволяет работать с окном просмотра Web-страницы в браузере. А уже в этот основной объект в качестве вложенных частей входят другие объекты, такие как screen, связывающий нас с экраном монитора пользователя, или document, открывающий доступ к содержимому самой Web-страницы. Полностыо эти объекты мы рассмотрим позднее.
Как уже было отмечено, мы не можем самостоятельно создавать свои объек ты. Но в этом и нет необходимости.
Мы можем объявлять переменные составного типа. Так, например, мы можем создать свой тип для комплексных чисел, которые содержат мнимую и действительную части. То есть, подобные комплексные числа описываются при помощи пары обыкновенных чисел. А создать переменную подобного комплексного типа достаточно просто. Для этого необходимо использовать специализированную функцию-конструктор. Выглядит этот процесс сле-дующим образом:
function complex(х, у)
{ this.x=x;
this.y«»y;
return this;
my_complex
new complex (5,2);
В этом примере мы видим, как создается функция-конструктор для комплексного типа чисел. А после кода функции следует объявление и инициа-лизация переменной при помощи оператора new, который используется для выделения памяти под создаваемые экземпляры объектов и составных пере-менных. Доступ к отдельным компонентам составной переменной осуществляется указанием их имени через точку, как
my_compiex.x. 1
И на этом мы заканчиваем рассмотрение структуры языка JavaScript. В этой главе мы постоянно будем пользоваться им для создания эффектов DHTML, поэтому все неясности будут устранены по ходу работы.