HTML: Популярный самоучитель

Чиртик Александр Анатольевич

Глава 12

Краткий курс JavaScript

 

 

Все, что было рассмотрено в предыдущих главах книги, относится к созданию хоть и красивых и удобных, но все же статичных веб‑страниц. Этого в большинстве случаев оказывается вполне достаточно. Однако по‑настоящему эффектными страницы получаются, если использовать при их создании возможности, предоставляемые большинством современных браузеров, – добавление в документы исполняемого содержимого.

Итак, исполняемым содержимым документа являются небольшие программы (названные сценариями), написанные автором документа и выполняющие в большинстве случаев несложные задачи по обработке данных или украшающие страницу.

Сценарии являются программами, поэтому естественно, что написаны они с использованием какого‑то языка программирования.

Среди языков, разработанных для программирования сценариев, можно привести JavaScript, VBScript, JScript как наиболее простые. В данной книге будет рассмотрено только программирование на языке JavaScript.

Язык программирования сценариев JavaScript претендует на то, чтобы быть упрощенной версией популярного языка Java, хотя во многих вопросах это сходство ограничивается только сходством в названии. JavaScript является интерпретируемым языком программирования (как и другие языки программирования сценариев). Это значит, что, когда наступает нужный момент, браузер находит в документе программу JavaScript, проверяет ее на наличие ошибок, после чего выполняет команду за командой.

Далее в этой главе рассматриваются основные возможности языка JavaScript и правила написания программ с его использованием.

Объем книги не позволяет привести развернутое описание языка программирования, поэтому материал изложен кратко.

 

12.1. Замечание о строках кода JavaScript

Логически цельные и обособленные действия программы на JavaScript, будь то присвоение значения переменной, вызов функции и пр., записываются в отдельных строках (эти действия называются операторами, или инструкциями). В конце строк обязательный для многих других языков программирования (для того же Java) символ ; ставить необязательно, за исключением тех случаев, когда нужно явно задать пустой оператор (в тех местах, где оператор требуется синтаксисом языка, но он не нужен программисту) или если все же нужно записать несколько действий в одной строке. Например:

var a, b = 123

a = a + 12 + b*2

a = a + b; c = a – b / 2

Однако во всех примерах книги строки заканчиваются символом ;, чтобы избежать путаницы (особенно для людей, которые уже имеют опыт программирования на C/C++ или Java). Выражения и операторы программы можно переносить на следующую строку, но только там, где допускается пробел. Например:

var a, b = В«textВ»

a = b + "=" + "Очень длинная строка текста, которая настолько длинна, что "+" даже не помещается на странице"

 

12.2. Комментарии

В тексте программы на JavaScript можно помещать два вида комментариев: однострочные и многострочные. Однострочный комментарий обозначается //, а многострочный заключается между /* и */. Примеры обоих видов комментариев:

//Однострочный комментарий

/* Многострочный комментарий */

 

12.3. Типы данных, переменные, выражения

Основные типы данных, которыми позволяет манипулировать JavaScript, приведены в табл. 12.1 (кроме того, существуют ссылки на объекты и функции, но они будут рассмотрены позже).

Таблица 12.1. Типы данных JavaScript

Перечисленные выше типы данных применяются в выражениях, например следующее выражение: 524 + 45.23 + «sometext» в результате даст значение «569.23sometext». Из полученного результата можно увидеть, что при расчете значений выражений производится автоматическое преобразование типов значений от менее универсальных типов к более универсальным (сверху вниз по табл. 12.1).

Относительно строковых значений осталось рассказать о том, что такое escape‑символы. Так вот, escape‑символы применяются для вставки в строки символов, которые не могут быть введены в текстовом редакторе либо являются недопустимыми (например, двойные кавычки в строке, заключенной в двойные кавычки). Доступные в JavaScript escape‑символы, а также их описания приведены в табл. 12.2.

Таблица 12.2. Escape-символы

Чтобы хранить значения выражений, используются переменные. Каждая переменная имеет имя (идентификатор). Имя переменной может содержать символы латинского алфавита, цифры и символ подчеркивания, причем первым символом не должна быть цифра, например: myVar, _any123var. Имена переменных не должны совпадать с зарезервированными словами языка JavaScript (они далее называются ключевыми, так менее точно, но короче). Ключевыми словами являются также все названия операторов, которые будут рассмотрены далее.

Переменные могут использоваться в выражениях наряду с численными и строковыми значениями (численными и строковыми константами). Например, если в переменной val содержится значение "text = ", то результатом выражения val + "sometext" будет строка "text = sometext".

Внимание!

Регистр символов в именах переменных, а также функций, классов (на будущее) в JavaScript имеет значение. Это значит, что, например, val и Val – это различные переменные.

Перед использованием переменные нужно объявлять. При этом тип переменной указывать не надо (определенных типов просто нет, есть тип, хранящий любые данные). Переменные объявляются при помощи ключевого слова var следующим образом:

var v1, somevar = В«asdВ»;

Как видно, в одной строке можно объявить сразу несколько переменных. При объявлении переменных их можно инициализировать (оператор = используется для присвоения значений переменным). Неинициализированные переменные содержат значение undefined (в данном случае это переменная v1). Переменные могут также содержать специальное значение null, означающее, что в переменной нет данных. Кроме того, можно использовать специальное значение NaN (Not a Number), сигнализирующее о том, что в переменной содержится не число.

Если необходимо определить тип выражения или тип значения, которое хранится в переменной, то можно использовать оператор typeof(выражение). Этот оператор возвращает строковые значения: number (для численных выражений или значения NaN), string (для строк), object (для значения null и ссылок на объекты).

 

12.4. Простые и составные операторы

Простыми операторами называются единичные конструкции, выполняющие какое‑нибудь действие, например вычисление значения одного выражения, присвоение значения, вызов функции и др.

В отличие от простых операторов, составной оператор может содержать в себе любое количество простых или вложенных операторов. Составной оператор задается (часто называемый блоком) при помощи скобок {}. Внутри этих скобок помещаются простые или вложенные составные операторы. Составные операторы используются, если нужно поместить несколько операторов, но ожидается присутствие только одного. В качестве примера рассмотрим оператор if (то, как работает этот оператор, описано далее). В теле оператора if ожидается наличие только одного оператора, выполняющего какое‑либо действие, например:

if (a == 1) a++;

Что же делать, если нужно выполнить последовательность более чем из одного оператора? Ответ: применить составной оператор так, как это сделано ниже:

if (a == 1) {

a++;

//Другие действия...

}

 

12.5. Операторы языка JavaScript

 

Арифметические операторы. Инкремент и декремент

В языке JavaScript присутствуют стандартные для языков программирования арифметические операторы, позволяющие производить вычисления с численными и строковыми значениями (для строк только оператор +).

К арифметическим операторам JavaScript относятся: + (сложение), – (вычитание), * (умножение), / (деление). В дополнение к ним присутствует оператор взятия остатка от деления %. Все указанные операторы являются бинарными (в том смысле, что принимают два значения и возвращают одно). Кроме указанных операторов, существует еще и унарный оператор –, инвертирующий значение аргумента (например –123, –val).

В JavaScript предусмотрена также удобная возможность записи выражений вида i = i + 1, i = i – 1, i = i * j и пр., где i – произвольная переменная, а j – произвольное выражение. Первые два выражения сокращенно записываются как инкремент и декремент: i++ и i–. Третье выражение и подобные ему можно сократить, применив следующие операторы:

• оператор –=, то есть i = i – j эквивалентно i –= j;

• оператор +=, то есть i = i + j эквивалентно i += j;

• оператор *=, то есть i = i * j эквивалентно i *= j;

• оператор /=, то есть i = i / j эквивалентно i /= j;

• оператор %=, то есть i = i % j эквивалентно i %= j.

Кроме того, предусмотрены соответствующие операторы &=, ^=, |= для двоичных операторов и <<=, >>=, >>>= для операторов сдвига.

 

Логические операторы и операторы сравнения

И логические операторы, и операторы сравнения возвращают результат – логическое значение true или false. Однако логические операторы принимают аргументы логического типа, в то время как операторы сравнения сравнивают значения произвольного типа. И логические операторы, и операторы сравнения языка JavaScript приведены в табл. 12.3.

Таблица 12.3. Логические операторы и операторы сравнения

 

Двоичные операторы

Двоичные операторы применяют при необходимости осуществления операций над численными (обычно целыми) значениями на уровне их битового представления. Здесь не рассматривается подробно, как представлены числа в памяти компьютера, а описываются только операторы.

Итак, двоичных операторов в JavaScript семь. Эти операторы перечислены в табл. 12.4.

Таблица 12.4. Двоичные операторы JavaScript

 

Приоритет операторов

Все операторы, которые могут быть использованы в выражениях, имеют свой приоритет, который учитывается при определении очередности вычисления значений подвыражений. Ниже приведен список операторов согласно их приоритету (от наивысшего к самому низкому).

1. ++, –, – (унарный), ~, !, typeof.

2. *, /, %.

3. +, -.

4. <<, >>, >>>.

5. >, >=, <, <=.

6. ==, !=, ===.

7. &.

8. ^.

9. |.

10. &&.

11. ||.

12. =, +=, –=, *=, /=, %=, &=, |=, ^=.

Несмотря на приоритет операторов, очередность вычисления подвыражений может быть изменена использованием скобок () любой вложенности. Выражение, заключенное в скобки, всегда вычисляется раньше других на том же уровне вложенности.

 

Условные операторы

При программировании на JavaScript можно использовать три условных оператора: if, select и оператор ? (именно вопросительный знак). Последний из операторов является самым простым, поэтому рассмотрим его в первую очередь.

Оператор ? используется как сокращенная версия оператора if при необходимости рассчитать значение одного из двух выражений в зависимости от истинности или ложности условия. Оператор имеет следующий формат:

условие ? выражение1 : выражение2

Здесь условие – логическое выражение (результат true или false). Выражение1 вычисляется в случае истинности выражения условие, иначе вычисляется значение выражения выражение2. Оператор ? возвращает значение (подобно любому другому оператору, например = или *), равное значению вычисленного выражения. Ниже приведено несколько примеров использования оператора ? (для большей наглядности выражения часто заключают в скобки):

a = (b > 3) ? b : 3; //Значение переменной a будет не меньше 3

a = (text == "continue") ? (a+=2) : a;

Следующим рассмотрим оператор if, который позволяет выбрать выполнение одной из двух последовательностей операторов в зависимости от истинности или ложности выражения‑условия. Оператор if имеет следующий формат:

if (условие) оператор1

else оператор2

Если значение выражения условие равно true, то выполняется оператор1 (это может быть как простой, так и составной оператор), в противном случае выполняется оператор2 (также или простой, или составной оператор). Часть else оператор2 является необязательной. Ниже приведено несколько примеров использования оператора if:

if (b != 0) a /= b; //Проверяется отсутствие деления на ноль

else {

//Какие-то действия по информированию (в данном случае ничего)

}

if (a > 12)

if (a<25); //Действия при 12 < a < 25

else; //Действия при a > 25

В приведенном примере проиллюстрирована одна проблема, с которой часто сталкиваются начинающие программисты на C‑подобных языках. Здесь специально проставлены отступы так, чтобы проиллюстрировать тот факт, что ключевое слово else относится к последнему по порядку оператору if. Если бы использовался блок, то принадлежность else была бы очевидной:

if (a > 12){

if (a<25) ; //Действия при 12 < a < 25

else ; //Действия при a > 25

}

Напоследок осталось рассмотреть последний из условных операторов – оператор множественного выбора switch. Он позволяет выбрать одну из многих альтернатив в зависимости от значения заданного выражения. Формат оператора приведен ниже:

switch (выражение){

case выражение1:

операторы1

case выражение2:

операторы2

...

default:

операторы_по_умолчанию

}

Оператор switch работает следующим образом. Сначала вычисляется значение выражения выражение. Далее это значение сравнивается с выражениями при каждом ключевом слове case сверху вниз. Если, например, значение выражение совпало со значением выражение2, то выполняется последовательность операторов операторы2. Выполнение продолжается до тех пор, пока не будет встречен оператор break либо выполнение не дойдет до конца тела оператора switch (закрывающая скобка }). Если перед следующим ключевым словом case отсутствует оператор break, то выполнится последовательность операторов операторы3 и т. д. Ключевое слово default используется для того, чтобы задать последовательность операторов, которые должны выполниться при несовпадении значения выражение со всеми выражениями при всех ключевых словах case. Для иллюстрации сказанного приводится пример использования оператора switch:

switch (var){

case 1:

//Операторы выполнятся при var == 1

break;

case 2:

//Операторы выполнятся при var == 2

case 3:

//Операторы выполнятся при var == 2 или var == 3

break;

case 4:

//Операторы выполнятся при var == 4

default:

//Операторы выполнятся при var != 1 && var != 2 && var != 3

}

 

Циклы

Язык JavaScript поддерживает три вида циклов: for, while и do-while. Начнем с более простых циклов while и do-while. Цикл while позволяет выполнять нужные действия, пока истинно выражение‑условие. Формат оператора while следующий:

while (условие) оператор

Здесь условие – логическое выражение (аналогично операторам if и ?), а оператор – простой или составной оператор, выполняемый при каждой итерации цикла. Пример использования цикла while:

var i = 0;

while (i<10){

//Какие-то действия...

i++; //Не забываем увеличить итератор, чтобы случайно

//не организовать бесконечный цикл

}

Следующий оператор цикла do-while имеет следующий формат:

do оператор while (условие)

Этот оператор цикла аналогичен оператору while с тем лишь отличием, что условие в цикле do-while проверяется после выполнения каждой итерации. Это значит, что оператор выполнится как минимум один раз. Предыдущий пример можно записать с использованием оператора do-while следующим образом:

var i = 0;

do{

//Какие-то действия...

i++; //Не забываем увеличить итератор, чтобы случайно

//не организовать бесконечный цикл

}while (i<10);

Теперь рассмотрим оставленный напоследок цикл for. Оператор for имеет следующий формат:

for (выражение1; условие; выражение2) оператор

Значение выражения выражение1 рассчитывается перед первой итерацией цикла. Обычно это инициализация счетчика или другой переменной, нужной в цикле. Операторы в теле цикла (оператор) выполняются до тех пор, пока истинно значение выражения условие. Перед второй и последующей итерациями вычисляется значение выражения выражение2 (обычно это выражение по изменению переменной цикла). Для демонстрации использования цикла for ниже приводится пример (аналог примеров для циклов while и do-while):

var i;

for(i=0; i<10; i++){

//Какие-то действия...

}

 

Операторы break и continue

Оператор break, помимо прерывания выполнения последовательности операторов внутри оператора switch, используется для прерывания итерации циклов. В следующем примере выполнение цикла for прерывается как раз с помощью оператора break:

var i;

for (i=0; i<10; i++){

//Действия...

if (i == 5) break;

}

Если в теле цикла встречается оператор continue, то остальные операторы игнорируются, а выполнение переходит на проверку условия цикла. Например, в следующем цикле суммируются значения от 1 до 10 (с помощью оператора continue игнорируются значения 5 и 7):

var i, sum = 0;

for (i=0; i<10; i++){

if (i == 5 || i == 7) continue;

sum += i;

}

 

Оператор запятая

Оператор полезен в тех случаях, когда нужно одновременно вычислить значение нескольких выражений в том месте, где допускается запись только одного. Рассмотрим этот случай на примере оператора for. Пусть нужно, чтобы в цикле было два итератора, но очень не хочется писать увеличение (уменьшение) одного из них в теле цикла. С использованием оператора , (запятая) можно разрешить проблему следующим образом:

var i, j;

for (i=0, j=100; i<j; i++, j–){

//Действия ...

}

Выражения, разделенные оператором , (запятая), вычисляются слева направо. При этом возвращаемым значением будет значение самого левого выражения. В следующем примере значение переменной res будет равным 3, а не 6:

var res, val = 2;

res = val+=1, val=5;

Из этого примера можно подчеркнуть одну особенность всех операторов присваивания языка JavaScript: они тоже возвращают значение. Корректными являются конструкции вида:

a = 1 + (b = c = d = 25);

Здесь значением переменной a будет 26, а остальных переменных – 25. Все сказанное об операторе , (запятая) не касается использования этого оператора при вызове функций.

 

12.6. Функции

 

Функции применяются в тех случаях, когда недостаточно программы, представляющей собой простую последовательность операторов, выполняющуюся один раз. В этом случае применение функций позволяет сгруппировать операторы и выполнять их произвольное количество раз (вызывая функцию из любого места программы). Упрощенно о функции можно сказать, что это именованная последовательность операторов.

 

Пользовательские функции

Пользовательская функция – любая функция, созданная программистом (а не встроенная в интерпретатор). Для создания пользовательских функций применяется следующая конструкция:

function имя_функции(параметр1, параметр2, ...){

//Операторы тела функции

return выражение

}

Здесь имя_функции – имя, идентификатор функции. На него распространяются те же ограничения, что и на имя любой переменной. В скобках задается список формальных параметров функции (она может и не иметь параметров). Каждый элемент этого списка – идентификатор переменной. Переменные с указанными в списке идентификаторами могут использоваться в функции так, как будто они были объявлены с использованием var (дополнительно эти переменные инициализируются значениями, переданными в функцию). Для возврата результата выполнения функции используется оператор return.

Рассмотрим пример функции, принимающей два значения и возвращающей сумму переданных ей значений:

function sum (v1, v2){

//Вычисляем сумму двух значений

return v1 + v2;

}

Для вызова этой функции в любом месте программы, а также в теле другой функции должна использоваться следующая запись:

sum(выражение1, выражение2)

Значения двух указанных выражений и будут переданы в функцию в качестве значений переменных v1 и v2. Если результат, возвращаемый функцией, используется, то в этом случае вызов функции записывают в правой части операторов присваивания либо как аргумент оператора в выражении, например:

summa = sum(3, 4); //В переменную summa заносится 7

summa = sum(3, sum(4, 5)); //Суммируются три значения

 

Встроенные функции JavaScript

Программист на JavaScript может использовать некоторые встроенные в интерпретатор функции, позволяющие значительно упростить некоторые аспекты программирования, связанные с преобразованиями строковых значений, вычислениями значений выражений. Эти функции приведены в табл. 12.5.

Таблица 12.5. Встроенные функции JavaScript

 

Глобальные и локальные переменные

При рассмотрении функций нельзя обойти вниманием такой вопрос, как область видимости переменных. Итак, переменные, объявленные вне функции, являются глобальными переменными. К ним можно получить доступ из любого места программы.

Переменные можно объявлять и внутри функций с использованием все того же ключевого слова var. Такие переменные являются локальными, и доступ к ним можно получить только внутри той функции, в которой они объявлены. Объявление любой локальной переменной может находиться в любом месте функции. При этом переменную, объявленную ниже в тексте программы, можно использовать выше, потому что интерпретатор при входе в функцию создает сразу все объявленные в ней переменные. В месте же объявления переменных происходит только их инициализация. Следующий пример является абсолютно корректным:

var j;

i = 1;

j = i;

var i = 2;

Рассмотрим также, что происходит, если имеет место такой случай:

var i = 1; //Глобальная переменная

function f(){

var i = 2; //Локальная переменная

return i;

}

В данном случае функция возвратит значение 2, то есть в операторе return используется значение локальной переменной.

 

Ссылки на функции

Кроме значений описанных ранее типов, переменным можно присваивать имена функций. После такого присвоения функцию можно вызвать, используя в качестве имени функции имя переменной, как в приведенном ниже примере:

var pfun = sum; //Присваиваем ссылку на функцию

var res = pfun(1,3); //Вызываем функцию sum

function sum(arg1, arg2){

return arg1+arg2;

}

Это может оказаться полезным во многих случаях. Например, в функциях сортировки массивов в число параметров функции сортировки часто включают параметр, предназначенный для передачи ссылки на функцию, сравнивающую элементы массива и возвращающую строго определенные значения (см. описание метода sort класса Array далее в тексте главы).

Кстати, оператор typeof возвращает значение function, если его параметром является имя функции или переменная, которой ранее присвоено имя функции.

 

12.7. Массивы

Использование массивов очень удобно, если нужно хранить большое количество однотипных значений. Массив – это список значений, хранящихся под одним именем. Доступ к каждому элементу массива осуществляется по номеру соответствующего элемента. Нумерация элементов массива в JavaScript начинается с нуля.

Массивы создаются в два этапа: объявляется переменная для хранения массива, после чего производится инициализация массива. Например:

var arr;

arr = [1,2,3,4,5];

или

var arr = [1,2,3,4,5];

Результатом выполнения приведенного фрагмента кода является создание массива, состоящего из пяти элементов. Доступ к элементам массива осуществляется с помощью оператора []. Операция получения значения третьего элемента массива выглядит следующим образом:

val = arr[2];

Конструкцию вида имя_массива[номер] можно использовать и в выражениях аналогично обычным переменным. Значения элементов массива можно сразу не указывать, то есть можно объявить пустой массив:

var arr;

arr = [];

Созданный массив при этом не содержит элементов. Для заполнения массива можно также использовать оператор []. Во время присвоения значений элементам массива проявляется следующая особенность: массив автоматически расширяется, если номер элемента, которому присваивается значение, превосходит номер последнего элемента в массиве. В следующем примере в результате выполнения присваивания массив будет содержать пять элементов, причем четыре первых из них будут иметь значение undefined:

var arr;

arr = [];

arr[4] = 5;

Для создания многомерного массива нужно элементам уже объявленного массива также присвоить массивы. Создание пустого двумерного массива (четыре строки с неопределенным количеством элементов) может выглядеть следующим образом:

var arr;

arr = [[], [], [], []];

Для обращения к элементам многомерного массива используется тот же оператор [], например:

arr[0][1] = 124;

arr[2][1] = arr[0][1];

Массивы в JavaScript являются объектами (оператор typeof для переменных‑массивов возвращает значение object). К тому же отсутствуют ограничения относительно формы, например, двумерных массивов: можно создавать как прямоугольные, так и треугольные или другие массивы произвольной формы. В ряде случаев это весьма полезно, но иногда может и запутать.

Размер массива можно получить с помощью свойства length этого объекта. Что такое свойство объекта и как его использовать, рассказано в следующем разделе.

 

12.8. Работа с объектами

 

Главная цель этого раздела – познакомить вас с приемами программирования на JavaScript, которые будут необходимы для организации взаимодействия с браузером и без которых сценарий в HTML‑документе совершенно бесполезен.

 

Понятие объекта. Свойства и методы

С точки зрения программиста, объект – это сложный тип данных, содержащий совокупность значений переменных (свойств) и функций для их обработки (методов). Все объекты одного и того же типа (с одним и тем же набором свойств и методов) представляют собой конкретные экземпляры одного класса.

Свойства объектов можно использовать в программе как обычные переменные, то есть можно присваивать и получать их значения. Методы объектов вызываются и возвращают значения так же, как и обычные встроенные или пользовательские функции.

Единственным существенным отличием использования свойств и методов объектов является необходимость указывать, к какому именно объекту относится свойство или метод. Это делается в программе с помощью оператора . (точка).

Объекты перед использованием необходимо создавать. Создание объектов осуществляется при помощи оператора new. Например, пусть есть класс point, содержащий свойства x и y, хранящие координату точки на плоскости, и метод distance(x, y), который позволяет рассчитать расстояние от точки с нужными координатами до точки, описываемой объектом. Тогда создание и использование объекта класса point можно проиллюстрировать следующим примером:

var p = new point; //Создание объекта класса point

p.x = p.y = 10; //Присвоение значений свойствам

var dist = distance(20, 0); //Вызов метода distance

В приведенном примере создавался пустой объект в том смысле, что изначально неизвестно, какое значение имеют свойства x и y только что созданного объекта. Если класс point поддерживает инициализацию при создании объектов, то присвоить начальные значения атрибутам можно следующим образом:

var p = new point(10, 10);

Примечание

При создании объекта оператором new происходит неявный вызов специального метода, называемого конструктором. Для одного и того же класса может быть предусмотрено несколько конструкторов, принимающих различное количество параметров. Поэтому в первом из приведенных выше примеров выполнялся конструктор, не имеющий параметров, а во втором – конструктор, принимающий два параметра.

Осталось сказать несколько слов об удалении объектов. Итак, JavaScript позаимствовал у Java такую особенность, как ненужность удаления объектов. Неиспользуемые объекты удаляются автоматически.

 

Встроенные классы JavaScript

После того как изложены основные принципы работы с объектами, можно кратко рассмотреть классы Array, Date, Number и String, которые могут очень пригодиться не только на начальном этапе освоения JavaScript. Кроме этих двух классов, нужно рассмотреть также объект Math, который может оказаться весьма полезным при создании различных визуальных эффектов.

Класс Array

Класс Array является достаточно удобным расширением обычных массивов. Главным образом за счет наличия дополнительных методов, позволяющих производить довольно сложные манипуляции с данными массива. Класс Array имеет следующие конструкторы:

Array()

Array(размер)

Array(элемент1, элемент2, ...)

При использовании первого конструктора создается пустой массив. При использовании второго конструктора создается массив с заданным количеством элементов. При этом все элементы созданного массива имеют значение undefined. При использовании последнего конструктора создается массив, количество элементов которого совпадает с количеством переданных в конструктор параметров. Значения параметров копируются в соответствующие элементы массива. Ниже приведены примеры объявлений массивов:

var arr1 = new Array(); //Пустой массив

var arr2 = new Array(5); //Массив из пяти неопределенных элементов

var arr3 = new Array(1,2,3,4,5); //Массив [1,2,3,4,5]

Размер массива можно узнать с помощью свойства length объекта Array. Доступ к элементам массива осуществляется с помощью [] по индексам элементов. Нумерация элементов, как и в случае обычного массива, начинается с нуля.

Как было сказано ранее, объект Array отличает ряд методов, ориентированных на работу с данными в массиве. Описания этих методов приводятся в табл. 12.6.

Таблица 12.6. Методы класса Array

Как можно заметить, большинство методов класса Array ориентированы на обработку одномерных массивов, но ничто не мешает создавать при помощи класса Array многомерные массивы. Для этого достаточно только присвоить элементам массива Array вложенные массивы, но только тоже созданные как объекты класса Array.

Теперь несколько слов о том, для чего методу sort() нужна функция сравнения. Так вот, для возрастающей или убывающей сортировки строковых значений в массиве использование метода sort() без написания своей функции сравнения не представляет трудностей (для убывающей сортировки достаточно после метода sort() вызвать метод reverse()). А вот приведенная ниже сортировка чисел даст не очень хороший результат:

var arr = new Array(5,2,25,16);

arr.sort();

В результате получится массив [16,2,25,5], а не [2,5,15,25]. Ошибки здесь нет, были отсортированы посимвольно строки из переданных чисел. Но в данном примере нужно сортировать числа. Для этого и пишется своя функция сравнения:

function comp(val1, val2){

if (val1>val2) return 1;

else

if (val1<val2) return –1;

else return 0;

}

Теперь вызов метода в виде sort(comp) приведет к правильной сортировке чисел по возрастанию. Задание своей функции сравнения дает большие возможности при обработке массива. Похожим образом можно очень просто сделать сортировку, например, двумерного массива по количеству элементов во вложенных массивах, по среднему значению, по сумме значений и т. д.

Класс Date

Объекты класса Date используются для хранения и обработки значений даты и времени. Конструкторы класса Date имеют следующий формат:

Date()

Date(миллисекунды)

Date(год, месяц, число, часы, минуты, секунды, миллисекунды)

При использовании конструктора без параметров созданный объект содержит текущую дату и время. Во втором варианте нужно указать количество миллисекунд, которое прошло с 00:00:00 01.01.1970 г. Третий вариант конструктора позволяет указать каждую составляющую даты и времени. При этом нужно учитывать один важный момент: год, месяц и число указывать обязательно, остальные параметры можно указывать только по мере необходимости. Однако если указываются, например, секунды, то нужно указать еще часы и минуты и т. д.

Кроме того, при использовании класса Date помните, что он оперирует датой и временем текущего часового пояса (локальным временем). Для перевода даты и времени в абсолютные значения (по Гринвичу, по универсальному времени) используются специальные методы этого класса.

В табл. 12.7 приводятся описание и формат основных методов класса Date.

Таблица 12.7. Методы класса Date

Класс String

Класс String является очень удобным средством манипулирования строками. Конструкторы класса String имеют следующий формат:

String()

String(строка)

Если используется конструктор без параметров, то созданный объект изначально хранит пустую строку. Если используется второй конструктор, то заданная в скобках строка станет начальным значением, хранимым в объекте:

var s = new String(В«some textВ»)

Класс String поддерживает свойство length, позволяющее получить длину строки. В классе String реализовано также большое количество методов, которые могут пригодиться при работе со строковыми значениями. В табл. 12.8 приведены наиболее используемые из этих методов.

Таблица 12.8. Методы класса String

Объект Math

При необходимости расчетов с привлечением различных математических функций и констант удобным оказывается использование объекта Math. Объект Math является глобальным объектом, создаваемым интерпретатором автоматически. Обращением к свойствам объекта Math можно получить точные значения различных математических констант (табл. 12.9).

Таблица 12.9. Свойства класса Math

Методы объекта Math представляют собой различные математические функции. Список методов приведен в табл. 12.10.

Таблица 12.10. Методы класса Math

Обращение к свойствам и методам объекта Math осуществляется аналогично обращению к свойствам и методам любого другого объекта, например:

var pi = Math.PI;

var rnd = Math.random();

Стоит сказать несколько слов об использовании функции генерации случайных значений Math.random(). Часто бывает необходимо получить не значение от 0 до 1, а случайное значение в каком‑либо определенном интервале. В этом случае можно использовать следующую функцию:

function rand(min, max){

return Math.random()*(max–min)+min;

}

 

12.9. Взаимодействие с пользователем

Одной из возможностей JavaScript по взаимодействию с пользователем является использование стандартных окон сообщений и окна ввода текста.

Программа на JavaScript может выводить два типа окон сообщений: окно с одной кнопкой OK и окно с кнопками OK и Отмена. Для вывода окон сообщений первого типа используется функция alert(), имеющая следующий формат:

alert(текст_сообщения)

Кроме текста сообщения, в функцию alert() можно передавать численные и логические значения, а также массивы, прочие объекты и даже функции (по крайней мере, при использовании Internet Explorer). Эти возможности делают функцию alert() удобным средством не только взаимодействия с пользователем, а также средством отладки сценариев.

Для вывода окна сообщения с возможностью выбора (кнопки OK и Отмена) используется функция confirm():

confirm(текст_сообщения)

Функция confirm() возвращает значение true, если пользователь нажал кнопку OK, и false, если нажата кнопка Отмена.

При необходимости организации ввода текста пользователем можно применять функцию prompt(). Функция имеет следующий формат:

prompt(текст_сообщения, текст_по_умолчанию)

Как видно, функция принимает два параметра. В первый параметр помещается комментарий, который будет показан в окне. Во втором параметре задается текст, который уже будет введен в текстовое поле, как только окно станет видным пользователю. Окно ввода, приведенное на рис. 12.1, появляется при выполнении следующего отрывка программы:

var a = prompt(«Введите свое имя», «Не хочу регистрироваться»));

Рис. 12.1. Окно запроса пользователю

Если пользователь нажимает в окне ввода кнопку OK, то функция prompt() возвращает введенное в текстовое поле значение. В противном случае функция prompt() возвращает значение null.

Примечание

Описанные в этом разделе функции вывода сообщений не являются специфичными только для JavaScript. Это методы глобального объекта window. Они рассмотрены раньше, чем объектная модель документа, ввиду чрезвычайной их полезности для отладки сценариев.

 

12.10. Поиск ошибок в программе

В заключение краткого рассмотрения языка JavaScript немного поговорим о видах ошибок в программе, а также о сообщениях об ошибках и поиске самих ошибок. Здесь идет речь об отладке программ (сценариев) средствами браузера.

Итак, синтаксические ошибки выявляются при проверке текста программы. Обычно они проявляются как несбалансированные скобки, не там поставленные запятые или точки с запятой, ошибки в выражениях и т. д. В сообщениях о синтаксических ошибках обычно фигурируют слова типа «ожидалось» (expected), «не ожидалось» (unexpected). Пример сообщения об ошибке браузера Internet Explorer приведен на рис. 12.2.

Рис. 12.2. Сообщение о синтаксической ошибке

Эту конкретную ошибку вызвала следующая строка программы (ошибочно использован символ ; вместо , для разделения параметров функции):

prompt(«текст сообщения»;"значение по умолчанию")

Семантическими ошибками являются использование необъявленных переменных, функций, неправильное количество параметров при вызове функций, использование операторов к операндам несовместимых типов и т. д. При отладке программ только с помощью браузера семантические ошибки равносильны ошибкам времени выполнения, так как выявляются только во время исполнения программы. При этом за браузером Internet Explorer (версии 6.0) замечено довольно странное отношение к ошибкам такого рода (хотя и оправданное с точки зрения пользователя). Так, сообщения об использовании необъявленных переменных часто не выдаются. Вместо этого интерпретатор JavaScript просто завершает выполнение функции или последовательности операторов вне функции. В следующем примере сообщения с номером 12 пользователь не увидит, если переменная a не объявлена:

a += 12;

alert(12);

При таком поведении интерпретатора браузера достаточно сложно определить место возникновения ошибки, поэтому приходится прибегать к некоторым уловкам. Например, можно расставлять вызовы функции alert() до и после каждого подозрительного места программы.