WWW.DISSERS.RU

БЕСПЛАТНАЯ ЭЛЕКТРОННАЯ БИБЛИОТЕКА

   Добро пожаловать!

Pages:     | 1 || 3 | 4 |   ...   | 6 |

«Вадим Дунаев JavaScript Изучите один из популярнейших языков для самостоятельно издание Прочитав эту книгу, вы узнаете: ...»

-- [ Страница 2 ] --

4. — добавляет к массиву указанное значение в качестве последнего элемента и возвращает новую длину массива.

Синтаксис:

Возвращает число. Совместимость: IE5.5+. Данный метод изменяет исходный массив.

5. — удаляет первый элемент массива и возвращает его значение.

Синтаксис:

Возвращает значение удаленного элемента массива. Совместимость: IE5.5+, NN4+. Данный метод изменяет исходный массив.

6. — добавляет к массиву указанное значение в качестве первого элемента.

Синтаксис:

Возвращает: ничего. Совместимость: IE5.5+. Данный метод изменяет исходный массив.

7. — изменяет порядок следования элементов массива на противополож ный.

Синтаксис:

Возвращает массив. Данный метод изменяет исходный массив.

Пример а = 2, "Звезда") /* массив с элементами в следующем порядке:

2, 1 */ 8. [, — создает массив из элементов исходного массива с индексами указанного диапазона.

Синтаксис: [, Возвращает массив. Данный метод не изменяет исходный массив.

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

Пример а = new 2, // массив с элементами: 2, "Звезда" // массив с элементами: "Звезда", "а", 72 1. Основы JavaScript 9. — сортирует (упорядочивает) элементы массива с помощью функции сравнения.

Синтаксис:

Возвращает массив. Данный метод изменяет исходный массив. Параметр не обязателен, о чем свидетельствуют квадратные скобки.

Если параметр не указан, то сортировка производится на основе сравнения ASCII-кодов символов значений. Это удобно для сравнения символьных строк, но не совсем подходит для сравнения чисел. Так, число 357 при сортировке счи тается меньшим, чем 85, поскольку сначала сравниваются первые символы и только в случае их равенства сравниваются следующие, и т. д. Таким обра зом, метод без параметра подходит для простой сортировки массива со строковыми элементами.

Можно создать свою собственную функцию для сравнения элементов массива, с помощью которой метод sortQ отсортирует весь массив. Имя этой функции (без кавычек и круглых скобок) передается методу в качестве параметра. При работе метода функции передаются два элемента массива, а ее код возвращает методу значение, указывающее, какой из элементов должен следовать за дру гим. Допустим, сравниваются два элемента, х и у. Тогда в зависимости от чи слового значения (отрицательного, 0 или положительного), возвращаемого функ цией сравнения, методом принимается одно из трех возможных решений:

Значение, возвращаемое Результат сравнения х и у функцией сравнения <0 у следует за х О Порядок следования х и у не изменяется х следует за у Итак, по какому критерию сортировать элементы массива, определяется кодом функции сравнения. Если элемент массива имеет значение null, то в Internet Explorer он размещается в начале массива.

Пример = new Array(4, 2, 15, 3, 30 ) // числовой массив function у) { функция сравнения return х-у } /* массив с элементами в порядке:

2, 3, 4. 15, 30 */ 10. количество [, [, элем2 [, — удаляет из массива не сколько элементов и возвращает массив из удаленных элементов или заменя ет значения элементов.

Синтаксис: количество [, [, элем2 [, Возвращает массив. Совместимость: IE5.5+. Данный метод изменяет исходный массив.

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

1.7. Встроенные объекты Пример а = new "Марья", 12, 5) х = /* х — массив элементов: "Иван", "Марья", а - массив элементов: "Вася", 5 */ Метод позволяет также заменить значения элементов исходного масси ва, если указаны третий и, возможно, последующие параметры. Эти параметры представляют значения, которыми следует заменить исходные значения эле ментов массива. При таком использовании метода важен первый пара метр (индекс), а второй (количество) может быть равным нулю. В любом слу чае, если количество элементов замены больше значения второго параметра, то часть элементов исходного массива будет заменена, а часть элементов будет просто вставлена в него. При этом метод возвращает другой массив, со стоящий из элементов исходного, индексы которых соответствуют первому и второму параметрам. Но это справедливо, если второй параметр не равен 0.

Пример а = new "Иван", "Марья", 12, 5) х = "Кузьма", "Анна") // х - массив элементов: "Иван", "Марья", - массив элементов: Кузьма", а = new "Иван", "Марья", 12, 5) х = "Кузьма", "Анна", "Федор", "Ханс") // х - пустой массив /* а - массив элементов:

"Кузьма", "Анна", "Федор", "Ханс" */ — преобразуют содержимое массива в символьную строку.

Метод поддерживается браузерами и NN3+, а метод — и более ранними версиями. Алгоритм преобразования по методу зависит от версии браузера.

Для преобразования содержимого массива в строку рекомендую использовать join().

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

Функция, возвращающая сумму значений всех элементов непустого массива:

function S(aN){ var for(var i = 1;

i<= i++){ S += S } Очевидно, для вычисления среднего значения следует просто воспользоваться выражением 74 Глава 1. Основы JavaScript Функция, возвращающая минимальное значение среди элементов массива:

function var = aN[0] for(var i <= i++){ if < Nmin) Nmin = aN[i] } return Nmi n } Функция, возвращающая максимальное значение среди элементов массива:

function var Nmax = aN[0] for(var i = 1;

1 <= -1;

i++){ if > Nmax) Nmax = aN[i] / return Nmax } Мы можем создать одну функцию, которая вычисляет все перечисленные выше статистические характеристики и возвращает их как значения массива:

function if (aN == 0 aN == || aN == return new var S = aN[0] var Nmin = aN[0] var Nmax = aN[0] for(var = l;

S += if (aN[i] < Nmin) Nmin = aN[i] if (aN[i] > Nmax) Nmax = aN[i] } return new Array(S, Nmin, Nmax) } В начале кода функции мы проверяем, не является ли параметр пустым.

Если это так, то все статистические характеристики считаются равными нулю.

1.7.3. Объект Number (Число) При разработке веб-страниц математические операции используются не столь часто, в отличие от строковых. Обычно они связаны с изменением координат эле ментов страницы (свойства top, left, width, height таблицы стилей). Однако встре чаются и более сложные случаи. Например, может потребоваться вычислить ста тистические характеристики данных, содержащихся в некоторой таблице. Так или иначе, в этих задачах необходимо иметь дело с числами. О числах мы уже говори ли в разделе, посвященном типам данных. Теперь рассмотрим их более подробно.

Числа в JavaScript В JavaScript числа могут быть только двух типов: целые и с плавающей точкой.

Целые числа не имеют дробной части и не содержат разделительной точки. Числа с плавающей точкой имеют целую и дробную части, разделенные точкой.

1.7. Встроенные объекты Операции с целыми числами процессор компьютера выполняет значительно бы стрее, чем операции с числами, имеющими точку. Это обстоятельство имеет смысл учитывать, когда расчетов много. Например, индексы, длины строк це лочисленными. Число л, многие числа, полученные с помощью оператора деле ния, денежные суммы и т. п. являются числами с плавающей точкой.

В JavaScript можно производить операции с числами различных типов. Это очень удобно. Однако при этом следует знать, какого числового типа будет результат.

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

Примеры целое число 2 + 3.6 // 5.6 — число с плавающей точкой 2.4 + 3.6 // 6 - целое число 6.00 // число с плавающей точкой Числа можно представлять и в так называемой экспоненциальной форме, то есть в формате: или Такая запись число Пример 1е5 // 100 2е6 // 2 000 1.5еЗ // +1.5еЗ // -1.5еЗ // - Зе-4 // 0. Числа в JavaScript можно представлять в различных системах счисления, то есть в системах с различными основаниями: 10 (десятеричной), (шестнадцатерич ной) и 8 (восьмеричной). К десятеричной форме представления чисел мы при выкли, однако следует помнить, что числа в этой форме не должны начинаться с О, потому что так записываются числа в восьмеричной системе.

Запись числа в шестнадцатеричной форме начинается с префикса Ох (или ОХ), где первый символ ноль, а не буква О, затем следуют символы цифр: О, 1, 9, а, с, d, e, f (буквы могут быть в любом регистре). Например, шестнадцатеричное число Ox4af в десятеричном представлении есть 1199.

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

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

function { = / строка, содержащая все 16-е цифры if > 255) return null Глава 1. Основы JavaScript var i = var j = (nl0 - i)/ = += rezult += return rezult // // // - склейка, а не сложение + 10 // Напомним, что выражение вида х += у эквивалентно выражению х = х + у.

Функцию можно также создать и на основе массивов:

function { hchars = new "1 "2", "3", "4", "5", "6", "a", if > 255) return null var i = var j = rezult = rezult += hchars[j] rezult += [i] return rezult Пример Функция преобразования из десятеричной в двоичную форму. Функция to2() в этом примере принимает в качестве параметра десятеричное число и преобразует его в строку, содержащую это же число, но во двоичной форме. Эта строка состо ит из нулей и единиц. Здесь используется рекурсивный вызов функции to2() са мой себя. Обратите внимание, что использование ключевого слова var здесь прин ципиально важно из-за рекурсии, иначе функция будет работать неправильно.

function { if <2) return + // чтобы результат был строковым var var return } Для преобразования строк, содержащих числа, в данные числового типа служат встроенные функции и соответственно для представления в целочисленном виде и в виде числа с плавающей точкой. Их мы уже рассматри вали выше. Здесь следует отметить, что параметрами этих функций могут быть строки, содержащие числа не только в десятеричной, но и в шестнадцатеричнои, и в восьмеричной формах. Для указания основания системы счисления служит второй параметр этих функций.

Примеры // значение равно // значение равно NaN 010") // значение равно 8) // значение равно 1.7. Встроенные объекты 10) // значение равно, 2) // значение равно 16) // значение равно Заметим, что функция в IE6.0 работает неправильно, если указан вто рой параметр (основание системы счисления).

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

Примеры + 25.78 // значение равно "25.78" + 2. 5еЗ // значение равно "2500" Создание объекта Number Числа можно создавать обычным образом с помощью переменных и оператора присвоения, не прибегая к объекту Однако этот объект обладает некото рыми полезными свойствами и методами, которые иногда могут пригодиться.

Объект создается с помощью выражения вида:

переменная = new Доступ к свойствам и методам строкового объекта обеспечивается такими выра жениями:

Свойства Number • — константа, значение которой равно наибольшему допустимому в JavaScript значению числа (1.7976931348623157е+308).

• — константа, значение которой равно наименьшему допустимому в JavaScript значению числа (5е-324).

• - меньшее, чем • - число, большее, чем • NaN — константа, имеющая значение NaN, посредством которой JavaScript со общает, что данные (параметр, возвращаемое значение) не являются числами (Not a Number).

• prototype — свойство (прототип), играющее такую же роль, что и в случае объ екта String (см. выше).

Методы Number Объект Number имеет несколько методов, из которых мы рассмотрим только четыре, предназначенные для представления чисел в виде строки в том или ином формате.

1. — представляет число в экспоненциальной форме.

Синтаксис:

Возвращает строку. Совместимость: IE5.5+, NN6+.

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

78 Глава 1. Основы JavaScript Примеры 2. — представляет число в форме с фиксированным количе ством цифр после точки.

Синтаксис:

Возвращает строку. Совместимость: IE5.5+, Параметр представляет собой целое число, определяющее, сколько цифр после точки следует указывать.

Примеры // x.toFi xed(2) // 25. // 25. // 25. 3. — представляет число с заданным общим количеством зна чащих цифр.

Синтаксис:

Возвращает строку. Совместимость: IE5.5+, Параметр представляет собой целое число, определяющее, сколько всего цифр, до и после точки, следует указывать.

Примеры x.toPrecision(6) // 135. x.toPrecision(5) // 135. // 135. // x.toPrecision(2) // 1.4e // // Сообщение об ошибке 4. — возвращает строковое представление числа в системе счисления с указанным основанием.

Синтаксис:

Возвращает строку. Если параметр не указан, имеется в виду десятеричная си стема счисления. Вы можете указать 2 для двоичной системы или 16 — для шест надцатеричной. Заметим, что этот метод имеют все объекты.

Примеры // "127.18" x.toString(10) // "127.18" x.toString(16) // // "177.134121727024366" Number(5) x.toStri ng(2) // "101" 1.7. Встроенные 1.7.4. Объект Math (Математика) Объект Math предназначен для хранения некоторых математических констант (например, число я) и выполнения преобразований чисел с помощью типичных математических функций. Доступ к свойствам и методам объекта Math обеспечи вается следующими выражениями:

Свойства Math Свойства объекта Math имеют в качестве своих значений математические константы.

F Постоянная Эйлера Значение натурального логарифма числа LN2 Значение натурального логарифма числа LOG10E Значение десятичного логарифма экспоненты (числа в) LOG2E Значение двоичного логарифма экспоненты PI Значение постоянной я Значение квадратного корня 1/ SORT Значение квадратного корня из Пример Для вычисления длины окружности при известном радиусе требуется число которое можно взять как свойство объекта Math.

var R = 10 // радиус окружности circus = // длина окружности Методы Math • — возвращает модуль (абсолютное значение) числа;

• — возвращает арккосинус числа;

• — возвращает арксинус числа;

• — возвращает арктангенс числа;

• atan2(x, у) — возвращает угол в полярных координатах точки;

• — округляет число вверх до ближайшего целого;

• — возвращает косинус числа;

• ехр(число) — возвращает число е в степени число;

• — округляет число вниз до ближайшего целого;

• — возвращает натуральный логарифм числа;

• — возвращает большее из чисел число2;

• — возвращает меньшее из чисел число2;

— возвращает в степени число2;

• — возвращает случайное число между 0 и 1;

• — округляет число до ближайшего целого;

• sin — возвращает синус числа;

• — возвращает квадратный корень из числа;

• — возвращает тангенс числа.

80 Глава 1. Основы JavaScript Примеры 1. Метод возвращает случайное лежащее в интервале от 0 до 1.

Чтобы получить случайное число в пределах от 0 до следует написать следующее выражение:

х = Если требуется получить случайное число в интервале от до Nmax, то из элементарного отношения пропорций получаем следующее выражение:

х = Nmin + (Nmax Можно также создать функцию для вычисления случайного числа в заданном интервале:

rand(a, b) { return a+ } Эта функция может потребоваться, например, для внесения некоторой непред сказуемости (нерегулярности) перемещения элементов на веб-странице, выбо ра цветов для мигающей надписи и т. п.

2. Для вычисления значения тригонометрической функции sin(x), у которой ар гумент х выражен в градусах, следует применить следующее выражение:

Функции для решения некоторых математических задач Язык JavaScript можно использовать не только для управления веб-страницами, но и для решения разного рода расчетных и математических задач. С другой сто роны, составление или анализ соответствующих программ является хорошим уп ражнением в программировании. Поэтому предлагаю вам рассмотреть несколько несложных, но полезных программ расчетного характера.

Решение квадратного уравнения С этой задачей мы знакомы еще со школы. Напомню, в чем она заключается. Тре буется найти два числа и такие, чтобы при подстановке любого из них в выражение + + с результат его вычисления был бы равен 0. Такие и называются корнями уравнения + + с = 0.

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

Организация же вычислений по конечным формулам из справочника — не самое сложное. Так, в рассматриваемой задаче в зависимости от значений коэффициен тов а, и с возможны различные частные случаи. Корни могут быть комплексны ми и действительными. нас интересуют только действительные корни.

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

Очевидно, функция (назовем ее для вычисления действительных корней квадратного уравнения должна принимать три параметра — коэффициенты a, b и с. Возвращаемым значением будет массив. Сделаем так, что если корней нет, то 1.7. Встроенные объекты этот массив будет пустым. В противном случае в нем будет два элемента. Если уравнение имеет два корня, то запишем их в качестве элементов возвращаемого массива. Если корень единственный, то он будет записан в первом элементе мас сива, а второй элемент будет пустым (null).

Ниже приводится один из возможных вариантов определения функции:

function beq(a, b, с){ // решение квадратного уравнения var aret = new var D = - 4*a*c if (a == 0) { if == 0)){ aret[0] = -c/b aret[l] = null }.

return aret // единственный корень или нет корней } if (D == 0) { // одинаковые корни if (D>0){ // различные корни aret[0] = aret[l] = + } return aret } Выполним проверку работы функции на нескольких наборах исходных данных:

beq(0, 2, 6) // массив (-3, null) beq(l, -2, 1) // массив (1, 1) beq(3, 4, -2.5) /* массив 0.4637216638542114) beq(2, 0. 5) // пустой массив Вычисление интеграла Интеграл от некоторого выражения / (х) с одной переменной х на интервале ее значений от а до b можно понимать как площадь, ограниченную кривой у = осью абсцисс (х) и двумя прямыми, параллельными оси ординат и проходя щими через точки а и b на оси (х). Аналогия с площадью справедлива лишь отча сти. Если указать, что площадь кривой, проходящей ниже оси абсцисс, является отрицательной, тогда все в порядке.

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

В качестве элементарной фигуры можно взять прямоугольник или трапецию. Их площади легко вычисляются. Однако трапеция вписывается в кривую лучше, чем прямоугольник, поэтому выберем именно ее. Напомню: чтобы найти площадь тра пеции, необходимо умножить полусумму ее параллельных сторон на высоту. Для 82 Глава 1. Основы JavaScript получения множества таких трапеций требуется разбить отрезок аЪ оси абсцисс на большое количество элементарных отрезков. В математике все идеально: отре зок ab разбивается на элементарные отрезки, длина которых стремится к нулю, то есть является бесконечно малой величиной. На практике мы имеем дело с ко нечными величинами. Более того, мы должны учесть, что с уменьшением длины элементарных отрезков и ростом их количества возрастает время вычислений.

Таким образом, нам потребуется найти компромисс между точностью решения задачи и временными затратами.

Теперь займемся технической стороной вопроса. Что следует передавать нашей функции вычисления в качестве параметров? Я вспомнил о великолепной встро енной функции eval(), которая может вычислять выражения JavaScript, передан ные ей в виде строки. Поэтому функция для вычисления интеграла бу дет принимать строку, содержащую выражение вида f(x), в котором переменная будет обозначена строчной латинской буквой х, например + 10". Два дру гих параметра — числа а и Ь, соответствующие концам интервала интегрирова ния. Ниже приведено определение функции function a, // интеграл var x, y2, n, length, length = - a) n = 100 // количество элементарных отрезков dx = // длина элементарного отрезка х = а /* начальное значение переменной х в выражении */ yl = х = а dx у2 = S = (yl + y2)' dx/ for(i=2;

i<=n;

i++){ yl = У x = x + dx y2 = S+= (yl + } return S } Проверим, как работает эта функция:

0, 1) (точное значение = 0.5) */, 0, 1) /* (точное значение = */, 0, 10) /* (точное значение = */ Если точность вычислений нас не устраивает, то это обусловлено малым значе нием n количества отрезков разбиения интервала ab. При большой длине этого интервала n = 100 будет явно недостаточно. Конечно, можно передавать это значе ние функции в качестве четвертого параметра. Однако я поступил иначе: если длина интервала больше 2, то n вычисляется по некоторой фор муле, а иначе n равно 100. Кроме того, я добавил проверки крайних случаев, что бы при них не возникало ошибок. В итоге получился следующий код:

function a, b){ // интеграл if !b&&!a) 1.7. Встроенные объекты return if (a == b) return var x, y2, n, length, length = - a) yl = // если левый предел больше правого b = b) // если правый предел меньше левого а = n = if (length>2) dx = // длина элементарного отрезка x = a /* начальное значение переменной х в выражении */ yl = x = а + dx у2 = S = (yl + y2)*dx/ yl = y x = x + dx y2 = S+= (yl + y2)*dx/ } ret urn S } Выполним проверку:

0, 10) /» (точное значение = */ Заметьте, что в данном случае точность после наших коррекций увеличилась на порядок.

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

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

Чем ближе расположены тестовые точки к заданной, тем точнее получается ре зультат. Мы выберем их так, чтобы заданная точка находилась посередине между тестовыми точками.

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

function // производная if // если нет выражения 84 Глава 1. Основы JavaScript return var x, у, dx = 0. x = a - dx // 1-я тестовая точка у = x = a + dx // 2-я тестовая точка return - y)/2/dx) } Проверочные примеры:

// (точное значение равно 1) 1) // (точное значение равно 2) Поиск экстремума Экстремум выражения (функции) f(x) — это пара чисел таких, что при в вместо этого выражения будет равно своему максимальному или минимальному значению Вообще го воря, функция может иметь несколько экстремумов или не иметь их вообще. Мы напишем код функции которая вычисляет экстремум выражения, если он действительно у него есть (график этого выражения имеет «холм» или Алгоритм решения задачи основан на том, что значение производной выражения в точке экстремума, или перегиба, равно 0.

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

function a, b, d){ // экстремум if (!d) d = 0. var x, i x = a yl = a) i = while <= b)&&(i <= { y2 = Dydx(expression, x+d) if { return new Array(x, ) x+= d У1 = У return new } Проверочный пример:

1, 0.01) /* -1) точное значение равно (0, -1) */ 1.7. Встроенные объекты ВНИМАНИЕ Если график выражения имеет несколько «холмов» или «впадин», то функция определит лишь один из них, ближайший к точке а.

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

Со временем дела обстоят не так просто, как кажется на первый взгляд. Вспомни те, что существуют временные зоны (часовые пояса), а также сезонные поправки времени. Так, например, текущее время в Санкт-Петербурге отличается от време ни в Иркутске на 5 часов. Если в Иркутске уже полночь, то в Петербурге еще только 19 часов. Чтобы иметь возможность координировать деятельность во вре мени организаций и физических лиц в различных точках нашей планеты, была введена система отсчета времени. Она связана с меридианом, проходящим через астрономическую обсерваторию в городе Гринвич в Великобритании. Эту вре менную зону называют средним временем по Гринвичу (Greenwich Mean Time — GMT). Недавно кроме аббревиатуры GMT стали использовать еще одну — UTC (Universal Time Coordinated — Всеобщее Скоординированное Время).

Если системные часы вашего компьютера установлены правильно, то отсчет вре мени производится в системе GMT. Однако на Панели управления обычно уста навливается локальное время, соответствующее вашему часовому поясу. При со здании и изменении файлов на вашем компьютере фиксируется именно локальное время. Вместе с тем операционная система знает разницу между локальным вре менем и GMT. При перемещении компьютера из одного часового пояса в другой необходимо изменить установки именно часового пояса, а не текущего системно го времени (показания системных часов). Даты и время, генерируемые в сцена риях, сохраняются в памяти в системе GMT, но пользователю выводятся, как пра вило, в локальном виде.

В программе на JavaScript нельзя просто написать 30.10.2002, чтобы получить значение даты, с которым в дальнейшем можно производить некие операции. Зна чения даты и времени создаются как экземпляры специального объекта Date. При этом объект сам будет «знать», что не бывает 31 июня и 30 февраля, а в високос ных годах 366 дней.

Создание объекта даты Объект даты создается с помощью выражения вида:

= new Параметры не обязательны, на что указывают квадратные скобки. Обратите вни мание, что имяОбъектаДаты является объектом даты, а не значением какого-нибудь другого типа (например, строкой или числом).

86 Глава 1. Основы JavaScript Для манипуляций с объектом даты применяется множество методов объекта Date.

При этом используется такой синтаксис:

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

переменная = Рассмотрим в качестве примера изменение значения года текущей системной даты:

xdate = new /* создание объекта, содержащего текущую дату и время */ Year = /* в переменной Year содержится значение текущего */ Year = Year /* в переменной Year содержится чем текущий год, на 3 */ /* в объекте устанавливается новое значение года */ При создании объекта даты с помощью выражения new DateQ, можно указать в качестве параметров, какие дату и время следует установить в этом объекте. Это можно сделать пятью способами:

new гггг new дд, гггг") new мм, дд, чч, мм, new Date(rr, мм, дд) new В первых двух способах параметры задаются в виде строки, в которой указаны компоненты даты и времени. Буквенные обозначения определяют шаблон пара метров. Обратите внимание на разделители — запятые и двоеточия. Время ука зывать не обязательно. Если компоненты времени опущены, то устанавливается значение 0 (полночь). Компоненты даты обязательно должны быть указаны. Ме сяц указывается в виде полного его английского названия (аббревиатуры не до пускаются). Остальные компоненты указываются в виде чисел. Если число мень ше 10, то можно писать одну цифру, не записывая ведущий 0 (например. 3:05:32).

В третьем и четвертом способах компоненты даты и времени представляются це лыми числами, разделенными запятыми.

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

Методы объекта Date Для чтения и изменения информации о дате и времени, хранящейся в объекте даты, служат методы объекта Date (табл. 1.3). Напомним, что объект даты создает ся с помощью выражения:

имяОбъектаДаты = new Затем, чтобы применить метод метод() к объекту даты имяОбъектаДаты, следует написать:

1.7. Встроенные объекты Довольно большое множество всех методов можно разделить на две категории:

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

Таблица 1.3. Методы объекта Date Метод Диапазон значений Описание Год Год 0-11 Месяц (январь = 0) 1-31 Число 0-6 День недели (воскресенье = 0) Часы в 24-часовом формате 0-59 Минуты 0-59 Секунды Миллисекунды с 1.1.70 00:00:00 GMT Миллисекунды с 1.1.70 00:00:00 GMT Год UTC 0-11 Месяц UTC (январь = 0) 1-31 Число День недели UTC (воскресенье = 0) 0-23 Часы UTC в 24-часовом формате 0-59 Минуты UTC Секунды UTC Миллисекунды UTC с 1.1.70 00:00:00 GMT Установка года (четырехзначного) 1970-... Установка года 0-11 Установка месяца (январь = 0) 1-31 Установка Установка дня недели (воскресенье = 0) 0-23 Установка часов в 24-часовом формате 0-59 Установка минут 0-59 Установка секунд 0-... Установка миллисекунд с 1.1.70 00:00:00 GMT 0-... Установка миллисекунд с 1.1.70 00:00:00 GMT Установка года UTC л Глава 1. Основы JavaScript Таблица 1.3 (продолжение) Диапазон значений Описание Метод Установка месяца UTC (январь = 0) 0- 1-31 Установка числа UTC Установка дня недели UTC (воскресенье = 0 ) Установка часов UTC в 24-часовом формате установка минут UTC 0-59 Установка секунд Установка миллисекунд UTC с 1.1.70 00:00: Разница в минутах по отношению к Строка с датой (без времени) в формате браузера Строка с датой и временем в глобальном формате Строка с датой без времени в локализован ном формате системы (NN6, Строка с датой и временем в локализованном формате системы Строка с временем без даты и в локализован ном формате системы IE5.5) Строка с датой и временем в формате браузера Строка с временем без даты в формате браузера (IE5.5) Строка с датой и временем в глобальном формате Преобразование строки с датой в число миллисекунд Преобразование строки с датой в число Вычислять разность двух дат или создавать счетчик времени, оставшегося до не которого заданного срока, можно с помощью методов как для локального форма та, так и для UTC. Не следует применять выражения, использующие различные форматы времени, поскольку результаты могут оказаться неправильными. Фор мат UTC обычно применяется в расчетах, учитывающих часовой пояс.

Следует также учитывать, что нумерация месяцев, дней недели, часов, минут и се кунд начинается с 0. Для компонентов времени это естественно. Однако при та кой нумерации декабрь оказывается месяцем в году, а не 12-м, как это при нято повсеместно. Воскресенье (Sunday) является 0-м днем недели, а не 7-м.

Значение года XX века представляется в двузначном формате как разность меж ду этим годом и 1900. Например, 1998 год представляется как 98. Годы до и после 1999 обозначаются в четырехзначном формате. Например, 2002 год нуж 1.7. Встроенные объекты но так и писать — 2002, поскольку 02 — это 1902 год. Метод getFullYear() возвраща ет четырехзначное значение года.

Примеры Допустим, что сейчас 2003 год.

today = new Date() // текущие дата и время Year = // today = new /* объект даты today содержит информацию о дате 6 ноября 1998 года, */ Year = // today Изменение любого компонента даты производится с метода, название которого начинается с приставки set. При этом значения других компонентов пересчитываются автоматически.

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

mydate = new Date(1952, 10,6) // Nov 6 00:00:00 1952" = mydate. // // установка 2003 года myday = // При попытке отобразить значение объекта даты оно автоматически преобразует ся в строку методом Формат этой строки зависит от операционной сис темы и браузера. Например, для Windows 98 и Internet Explorer 5.5 строка, содер жащая информацию объекта даты, имеет следующий вид:

Thu Oct 31 13:16:23 UTC+0300 2002, то есть четверг, октябрь, 31, 13 часов 16 минут 23 секунды всеобщего времени, скорректированного на 3 часа, 2002 год.

Если коррекцию времени с учетом часового пояса производить не требуется, то для строкового представления даты и времени можно воспользоваться методом mydate = new mydate. // "31 октября 2002 г. 14:15:30" В браузерах и работают еще два метода представления отдельно даты и времени в виде строки:

mydate = new DateO mydate. toLocaleDateStringO // "31 октября 2002 г."

// "14:15:30" Заметим, что формат представления даты и времени, обеспечиваемый методами и зависит от настроек операционной систе мы и браузера. Если вы будете использовать эти методы для вывода даты и време ни на веб-страницу, то они будут выглядеть так, как пользователь привык их ви деть на своем компьютере.

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

90 Глава 1. Основы JavaScript Примеры Определим дату, которая наступит через неделю относительно текущей:

week = 1000*60*60*24*7 /* количество миллисекунд в неделе - 604800000 */ = new Date() // объект даты с текущей датой = /* текущая дата, представленная количеством миллисекунд от 1.01.1970 00:00:00 */ mydate_ms += week // = + week /* установка новой даты в объекте mydate */ newdate = // новая дата в виде строки 2. Определим количество дней между двумя датами, например 10 февраля и 5 марта 2003. Для этого создадим сначала два соответствующих объекта даты:

= Date( date2 = new Переменные datel и содержат длинные строки, содержащие даты (напри мер, Feb 10 00:00:00 UTC+0300 2003). Чтобы перевести их в количество мил лисекунд, воспользуемся методом parse() объекта Date. Затем вычислим разность и и разделим ее на количество миллисекунд в одних сутках:

days = // результат: 3. Часто приходится иметь дело с датами, представленными в виде строк в фор мате причем месяцы нумеруются с 1 до 12, а не с 0 до 11. В этом случае, чтобы воспользоваться методами объекта Date, необходимо предвари тельно выполнить соответствующие преобразования.

Допустим, исходная дата strdate представляется в виде строки в формате "дд.мм.гггг", а для создания объекта даты используется формат параметров мм, Тогда необходимые преобразования исходных данных выглядят сле дующим образом:

astrdate = /* массив подстрок, полученных из строки strdate с использованием точки как разделителя */ /* создаем объект даты */ mydate = new Date(astrdate[2], 4. Развивая идею, рассмотренную в предыдущем примере, мы могли бы создать функцию, принимающую в качестве параметра строку, содержащую дату и время в привычном для нас формате и возвращающую объект даты. Будем считать, что в строке параметра нашей функции дата отде лена от времени одним пробелом, однако допускается, что информации о вре мени вообще может не быть. Далее, если время присутствует, секунды не обя зательно должны указываться. Если параметр является пустой строкой или вообще отсутствует, то функция возвращает объект с текущей датой.

function if (strdate == || strdate == null) { return new Date() } var astrdate = 1.7. Встроенные объекты if == 1) astrdate[l] = "00:00:00" astrdate[0] = = if == 1) astrdate[l] = new else { if == 2) = new, "00") } return new [2],, } Заметим, что в действующем коде выражение с последним оператором return не обходимо написать в одну строку.

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

= date2 = days = Иногда в приложениях, в том числе и на веб-страницах, устанавливают часы (тай мер), показания которых постоянно изменяются в соответствии с ходом систем ных часов. Чтобы сделать это, требуется в цикле создавать объект даты и форми ровать строку из компонент времени, используя подходящие для этого методы.

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

1.7.6. Объект Boolean (Логический) Объект Boolean создается с помощью выражения вида:

переменная = new Он имеет свойство prototype, методы и значение которые имеют также объекты String и Number.

Смысл свойства prototype мы уже рассматривали применительно к объектам String и Array. Объект Boolean может понадобиться в том случае, когда всем логическим объектам, создаваемым с помощью выражения с ключевыми словами new Boolean, нужно добавить новые свойства или методы с помощью прототипа (свойства prototype).

1.7.7. Объект Function (Функция) Создание объекта Function Выше мы уже рассматривали стандартный способ определения функции:

function { код Глава 1. Основы JavaScript Существует и другой способ, основанный на выражении с ключевыми словами new Function. Согласно этому способу функция создается как экземпляр объекта Function:

= new Названия всех параметров являются строковыми значениями. Они разделяются запятыми. Заключительная строка содержит операторы кода тела функции, раз деленные точкой с запятой.

Вызов функции, определенной как экземпляр объекта Function, можно выполнить обычным способом:

Примеры Srectangle = new "height", s = return s") 3) // возвращает var expr = "var s = return s" Srectangle = new "height", expr) Srectangle(2, 3) // возвращает a = b = "height" expr = "var s = return s" Srectangle = new Function(a, b, expr) 3) // возвращает б При любом задании функции, стандартном или с помощью ключевого слова new, автоматически создается экземпляр объекта Function, который обладает своими свойствами и методами.

Свойства Function 1. arguments — массив значений параметров, переданных функции.

Индексация элементов массива производится с 0. Поскольку это массив, он имеет свойства и методы объекта Array (в частности, свойство length — длина массива).

Свойство arguments применяется в теле определения когда требуется проанализировать параметры, переданные ей при вызове. Например, можно узнать, сколько в действительности было передано параметров, не являются ли их значения пустыми 0, null) и т. п. Это свойство особенно полезно при раз работке универсальных библиотечных функций.

Синтаксис выражения следующий:

Пример Функция, приводимая в этом примере, возвращает строку, содержащую значе ния параметров и их общее количество, которые были указаны в вызове функ ции (а не в ее function myfunc(a, b,c){ var /* количество переданных параметров */ var for { 1.7. Встроенные объекты _ х += } return ) myfunc(5, "Вася") // "5, Вася, Всего: 2" // "Всего: 0" // 4" 2. Length — количество параметров, указанных в определении функции.

Синтаксис:

В отличие от свойства arguments, количество параметров функции можно опре делить в программе за пределами тела этой функции.

Пример function myfunc(a, b, с, return } // // 3. caller — содержит ссылку на функцию, из которой была вызвана данная функ ция;

если функция не вызывалась из другой функции, то значение этого свой ства равно null.

Совместимость: IE4+, NN4.

Синтаксис:

В свойстве содержится все определение функции, из кото рой была вызвана функция Пример function fl() { f2() } f2() // диалоговое окно со значением Вызов функции fl() приведет к вызову функции которая выведет на экран окно с сообщением, содержащим код определения функции fl() (рис. 1.12).

Рис. 1.12. Результат выполнения функции fl() — окно со значением Методы Function toString() — возвращает определение функции в виде строки.

Синтаксис:

94 Глава 1. Основы JavaScript Иногда этот метод используют в процессе отладки программ с помощью диалого вых окон.

Пример function myfunc(a, b){ return a*b/ } alert Результат выполнения последнего выражения показан на рис. 1.13.

\.

OK Рис. 1.13. Результат выполнения call( [ Оба метода используются для вызова функции и дают одинаковые результаты.

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

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

Пример /* Функция-конструктор объекта function color) { = name // название = model // модель = color // цвет = showcar // метод I /* Функция, вызываемая как метод объекта car */ function + + // окно с сообщением /* Создание экземпляра объекта car */ • mycar = new Обычный способ применения метода show к объекту car (вывод окна с сообщени ем) выглядит так:

1.7. Встроенные объекты При этом в действительности вызывается функция заданная для этого метода. Текущий объект рассматривается как контекст для ссылок ука занных в теле функции.

Однако методы apply() и позволяют не связывать функцию с объек том mycar. Более того, в конструкторе объекта можно не указывать выражение, определяющее функцию в качестве метода объекта. Вместо этого можно вызвать метод showcar как объект и применить к нему метод указав в каче стве параметра mycar как текущий объект:

С помощью метода можно передавать параметры, отделенные друг от друга запятыми. Если параметры определены как элементы массива, то вместо используется метод 1.7.8. Объект Object Object является корневым объектом, на котором базируются все остальные объек ты JavaScript, такие как String, Array, Date и т. д. В программах можно создавать свои собственные объекты. Это можно сделать различными способами.

Способ function код > = new Способ имяОбъекта = new Object() = значение Способ имяОбъекта = [, свойство2: значение2 [ • Для обращения к свойствам и методам объекта используется следующий синтаксис:

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

function Отдел, Телефон, Зарплата) { = Имя = Отдел = Телефон = Зарплата } Как видите, конструктор объекта может быть представлен в виде определения функции. Ключевое свойство this представляет ссылку на текущий, то есть оп ределяемый конструктором объект. Все операторы присвоения с this, расположен ные в теле функции-конструктора, определяют свойства объекта. В круглых скоб ках у имени объекта могут перечисляться параметры, чтобы иметь возможность 96 Глава 1. Основы JavaScript создать конкретный объект, являющийся экземпляром обезличенного объекта Сотрудник, и присвоить его свойствам конкретные значения. Например, создадим конкретного сотрудника — = new Бонд", 5, "223-332", 3600.50) Доступ к свойствам этого объекта производится обычным способом:

// "Джеймс Бонд" // 3600. Информация о новом сотруднике добавляется аналогичным образом:

= new 4, "123-4567", 4500.50) К свойствам и методам этого объекта обращаются довольно редко, и здесь мы не будем их подробно рассматривать. Отметим свойство prototype, назначение кото рого мы уже описывали применительно к объектам String и Array. Метод обычно используется при отладке программ с помощью диалоговых окон. Свой ство используется, чтобы определить, имеется ли у эк земпляра объекта указанное свойство, определенное в его конструкторе (но не с помощью prototype). Если да, то возвращается true, в противном случае — false.

Более подробные сведения о создании объектов вы найдете в следующем разделе.

Там приведено много примеров, и вы легко убедитесь, что понятие объекта не сложнее, чем понятие функции.

1.8. Пользовательские объекты В предыдущем разделе мы рассмотрели встроенные объекты, то есть заранее пред определенные в JavaScript и часто используемые в программах. С помощью выра жений с ключевым словом new вы можете создавать экземпляры этих объектов, то есть их конкретные воплощения. Более того, благодаря свойству prototype име ется возможность добавлять к объектам новые свойства и методы, придуманные пользователем и отсутствовавшие в исходных встроенных объектах. В большин стве случаев, в частности при создании сценариев для веб-страниц, всего этого более чем достаточно. Однако нельзя обойти вниманием возможность создания собственных объектов. Зачем нужны собственные объекты?

Они не являются необходимыми для решения практических задач. С точки зре ния программиста, объект представляет собой просто удобное средство организа ции данных и функций их обработки. Чтобы как-то организовать данные и функ ции в программе, далеко не всегда необходимо прибегать к такой конструкции, как объект. Ведь даже при внушительном количестве данных программист не все гда организует их в виде массива (объекта Array): бывает достаточным ограничиться простыми переменными.

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

1.8. Пользовательские объекты 1.8.1. Создание объекта Объекты в JavaScript можно создать несколькими способами. Мы рассмотрим три из них.

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

Имя функции-конструктора объекта является одновременно и именем создавае мого объекта. Свойства и методы создаваемого объекта задаются в теле функции конструктора с помощью операторов присвоения. При этом имена переменных свойств записываются с ключевым словом this (этот):

Рассмотрим в качестве примера функцию-конструктор, определяющую объект (автомобиль) со свойствами (название), model (модель) и color (цвет):

function car(name, model, color) { = name = model = color } Эта функция объект car. Чтобы создать конкретный экземпляр объек та следует выполнить выражение с вызовом этой функции, которой можно передать значения параметров. Мы уже знаем, что экземпляр объекта создается с помощью оператора присвоения с ключевым словом new:

= new Итак, мы создали объект mycar, являющийся экземпляром объекта Таких эк земпляров с различными именами можно создать несколько. Значения свойств объекта mycar можно изменять в программе:

// значение равно // значение равно "Ока" = // значение равно Как видите, объект — это просто особый способ группировки данных и их исполь зования (составное имя переменной:

Объекты можно создавать и с помощью конструктора new mycar = new = "Ока" = = "whi te" В этом способе отчетливо видно: создаваемый объект является экземпляром объ екта Object, подобно тому как, например, создаваемый массив является экземпля ром объекта Array.

Допускается также и следующая компактная запись определения объекта:

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

98 Глава 1. Основы JavaScript При создании объекта мы можем задать значения свойств по умолчанию, то есть значения, которые будут иметь свойства, если при создании экземпляра этого объ екта значения его свойств не указаны явным образом (то есть имеют значения null, 0 или Это делается с помощью логического оператора ИЛИ (обозначаемо го ||) в конструкторе объекта в виде функции:

function car(name, color) { // конструктор объекта саг = name || "неизвестно" = model = color "black" } = new // создание экземпляра mycar объекта car // "Жигули" // "неизвестно" // "black" 1.8.2. Добавление свойств Если возникает необходимость добавить новое свойство к существующему объек ту, а также ко всем его экземплярам, то это можно сделать с помощью свойства prototype. В приведенном ниже примере мы создаем объект (автомобиль), за тем его экземпляр а затем добавляем к свойству prototype свойство owner (владелец) с конкретным значением:

function car(name, model, color) { // конструктор объекта car = name || = model "неизвестно" = color || "black" } mycar = new /* создание экземпляра mycar объекта car */ mycar.name // "Жигули" // "неизвестно" // "black" = "Иванов" // добавляем новое свойство // "Иванов" Если нужно добавить новое свойство только к конкретному объекту (к данному экземпляру объекта), то это можно сделать просто с помощью оператора присво ения:

= значение В следующем примере мы создаем объект вообще без свойств, а затем добав ляем его экземпляры и к ним — различные свойства.

function = new car() mycar2 = new = "Жигули" = // "Жигули" // undefined (не определено) // undefined (не // 1.8. Пользовательские объекты 1.8.3. Связанные объекты В объекте в виде свойства может содержаться ссылка на другой объект. В этом случае оба объекта оказываются связанными: один из них оказывается том или, другими словами, свойством другого. Например, мы можем создать объ ект photo, содержащий в качестве своих свойств название автомобиля и URL-адрес файла с его изображением. Такой объект можно связать с объектом содержа щим основную информацию об автомобилях, добавив к нему свойство, значени ем которого является ссылка на объект photo.

Ниже приведены конструкторы объектов и photo. Чтобы добавить объект photo в объект мы добавили в объект свойство, значением которого является ссыл ка на объект photo.

function car(name, model, color, photo) { // конструктор объекта car = name = model = color = photo // ссылка на объект photo function photo (name, { // конструктор объекта photo = name thi = url Создадим пару конкретных объектов, являющихся экземплярами объекта photo:

photol = new j photo2 = new photoC'OKa",. gi Теперь создадим экземпляры объекта car:

= new photol) // // mycar = new photo2) // // Обратите внимание: чтобы узнать значение URL-адреса расположения файла с картинкой, относящейся к объекту mycar, мы обращаемся к свойству urL объекта photo, который сам является свойством объекта mycar или, другими словами, под объектом объекта mycar.

1.8.4. Пример создания базы данных с помощью объектов Теперь рассмотрим пример создания базы данных автомобилей, находящихся на одной стоянке. Список всех автомобилей можно представить в виде таблицы со столбцами: name (название), (модель), (номер), owner (владелец) и photo (фотография). Будем считать, что на фотографии номер автомобиля не показан, так что она отображает не конкретный автомобиль, а его тип (название, модель и цвет). Конечно, можно создать базу данных в виде одной таблицы, одна ко мы поступим иначе и создадим две таблицы. Одна из них будет вспомогатель 100 Глава 1. Основы JavaScript ной и выполнять роль справочника типов автомобилей, а другая таблица будет содержать записи о конкретных автомобилях, находящихся на стоянке или, точ нее, приписанных к ней.

Справочник типов автомобилей будет содержать наиболее общие сведения об автомобилях: название, модель и фотографию (точнее, URL-адрес ее файла). На стоянке может находиться несколько автомобилей одного типа (например, «Жи гули», ВА32101 белого цвета), но в справочнике этот тип будет упомянут лишь один раз. В нашей базе данных справочник типов автомобилей будет представ лять объект function ref(name, model, url) { /* конструктор справочника типов автомобилей */ = name // название марки автомобиля = model // модель = url // URL-адрес файла с фотографией } Заполним справочник конкретными записями. Множество всех таких записей удобно определить как массив (назовем его aref). Тогда элементы этого массива определим как экземпляры объекта ref:

aref = new // массив записей справочника типов автомобилей aref[0] = new aref[l] = new aref[2] = new aref[3] = new, В нашем справочнике описаны только четыре типа автомобилей.

Теперь создадим список всех автомобилей на стоянке. Этот список удобно офор мить как массив, каждый элемент которого представляет запись о конкретном автомобиле. Формально элементы этого массива мы определим как экземпляры объекта который будет содержать ссылку на справочник — объект ref.

Итак, сначала напишем код функции-конструктора объекта function car(regnum, owner, ref) { = // номер автомобиля = owner // владелец = ref // ссылка на справочник } Далее создадим записи о конкретных автомобилях стоянке. Массив записей назовем acar = new ArrayO = new acar[l ] = new "Петров", acar[2] = new acar[3] = new "Михайлов", acar[4] = new "Дунаев", acar[5] = new "Павлов", acar[6] = new "Николаев", В нашем списке всего 7 записей. Модель в нем встречается два раза, ГА324 — три раза, а остальные — по одному разу. Если бы мы создавали базу дан ных без справочника, то нам пришлось бы многократно повторять одни и те же данные при определении массива Далее приводятся примеры обращения к свойствам нашей базы данных:

1.8. Пользовательские объекты // // "Волга" // "Михайлов" Поскольку база данных представляет собой массив, с помощью методов объекта Array можно организовать фильтрацию (выборку) записей по тому или иному кри терию. Попробуйте сделать это самостоятельно.

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

, ,
, и др. Вы можете создать в HTML-программе раз дел, обрамленный тегами , между которыми разместить рас смотренный выше код на языке JavaScript. А далее есть два пути.

• Вручную написать теги таблицы. Если количество строк в таблице невелико, то именно так и следует поступать.

• Написать программу на JavaScript, генерирующую нужную последовательность тегов и данных как строку, а затем воспользоваться методом объекта document для ее записи в текущий HTML-документ и исполнения браузером.

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

В листинге 1.1 приведен HTML-код, содержащий только сценарий. Для упроще ния ситуации мы формируем таблицу только с тремя столбцами. Мы не обраща ли внимания на дизайн таблицы, определяемый специальными атрибутами тегов (рис. 1.14).

данных автомобилей - E Номер Жигули I (Жигули Жигули Волга Ока Волга I | : | Мои Рис. 1.14. Так выглядит база данных автомобилей в окне браузера Глава 1. Основы JavaScript Листинг 1.1. Код для отображения базы данных автомобилей в браузере данных Здесь в теле оператора цикла for мы использовали разновидность оператора при своения +=. Напомним, что выражение х += у эквивалентно выражению х = х + у.

Мы дважды использовали выражение с этим оператором только лишь для того, чтобы выражение справа от него не было слишком длинным.

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

SRC = + + 1.9. Специальные операторы 1.9. Специальные операторы В этом разделе описываются операторы, которые при программировании на Java Script используются относительно редко. Возможно, они вам когда-нибудь по требуются. Именно поэтому я и включил в книгу данный раздел. Новички могут пока пропустить его.

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

В конце концов эта последовательность битов преобразуется к обычному целому числу — результату побитового оператора. В табл. 1.4 приведен список побито вых операторов.

Таблица 1.4. Побитовые операторы Оператор Название Левый операнд Правый операнд к Побитовое «и» Целое число Целое число Побитовое «или» Целое число Целое число Побитовое исключающее Целое число Целое число «или» Побитовое «не» Целое число Смещение влево Целое число Количество битов, на которое производится смещение Смещение вправо Целое число Количество битов, на которое производится смещение Заполнение нулями при Целое число Количество битов, на которое смещении вправо производится смещение Операторы &, и ~ напоминают логические операторы, но их область действия биты, а не логические значения. Оператор - изменяет значение бита на противопо ложное: 0 на 1, а 1 — на 0. В табл. 1.5 поясняется, как работают операторы &, |, Таблица 1.5. Работа операторов &, X Y X|Y 1 1 1 1 1 0 0 1 0 0 i 0 0 0 0 104 Глава 1. Основы JavaScript Например, 2&3 равно 2, а равно 3. Действительно, в двоичном представлении есть 10, а 3 — Применение побитовых операторов даст в случае оператора & двоичное число 10, то есть десятеричное число 2, а в случае оператора | — двоич ное число И, то есть десятеричное 3.

У операторов смещения один операнд и один параметр, указывающий, на какое количество бит следует произвести смещение. Например, равно 12, потому что смещение влево на два бита двоичного числа (десятеричное 3) дает что в десятеричной форме есть 12. Результат вычисления выражения — 1.

Действительно, число 6 в двоичной форме это смещение его вправо на два бита дает 1 как в двоичной, так и в десятеричной форме.

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

delete элемент ВНИМАНИЕ При удалении элемента массива удаляется и его индекс, но оставшиеся элементы сохра няют свои прежние индексы, а длина массива не изменяется.

Пример myarray = new // delete // myarray[0] // "a" // undefined myarray[2] // // "d" Использование оператора delete не приводит к немедленному освобождению па мяти. Решение об освобождении памяти принимается так называемым ядром JavaScript, а пользовательская программа лишь создает к этому предпосылки, но не может контролировать этот процесс абсолютно.

Оператор проверки наличия свойств (in) Этот оператор позволяет проверить, имеется ли некоторое свойство или метод у того или иного объекта. Левый представляет собой ссылку в виде стро ки на интересующее нас свойство или метод, а правый операнд — объект. Ссылка на метод содержит лишь его название без круглых скобок. Если свойство или ме тод содержится в объекте, то возвращается true, иначе — false. Отсюда следует, что оператор in можно применять в условных выражениях (в операторах if, switch, for, while, do-while).

Примеры Например, объект document, представляющий загруженный в браузер HTML-доку мент, имеет метод Чтобы убедиться в этом, следует написать выражение 1.9. Специальные операторы " wr i t e" i n document // значение равно true 2. Создадим объект и проверим наличие в нем некоторых свойств.

function Зарплата) { = Имя = Отдел = Телефон = Зарплата I agent007 = new Бонд", 5, "223-332") "Телефон" in agent007 // true "Ученая степень" in // false Оператор in поддерживается браузерами NN6+.

Оператор проверки принадлежности объекта модели (instanceof) Этот оператор позволяет проверить, принадлежит ли некоторый объект объект ной модели JavaScript. Левый операнд представляет проверяемое значение, а правый — ссылку на корневой объект, такой как Array, String, Date и т. п. Вы ражение с оператором instanceof возвращает true или false и, таким образом, может использоваться в условных выражениях (в операторах if, switch, for, while, do-while).

Пример Созданный массив является экземпляром объекта Array, а последний сам являет ся экземпляром корневого объекта Object.

myarray = new myarray instanceof Array // true Array instance // true Myarray instanceof // false Оператор in поддерживается браузерами NN6+.

1.9.3. Комплексные операторы Оператор условия (?:) Этот оператор является сокращенной формой оператора условного перехода else... Его так и называют: оператор условия. Обычно он используется вместе с оператором присвоения одного из двух возможных значений, в зависимости от значения условного выражения. Синтаксис оператора условия следующий:

условие ? :

С оператором присвоения оператор условия имеет такой вид:

переменная = условие ? :

Оператор условия возвращает значение выражения если условие ис тинно, в противном случае — значение выражения Пример d = new Date() х = typedate = == 0)&&(x > 1) ? "четное" : "нечетное" 106 1. Основы JavaScript Если бы в JavaScript не было оператора условия, то пришлось бы написать функ цию, которая работала бы как оператор условного перехода if, но, в отличие от него, возвращала значение. Вот пример этой функции:

function expr2){ if return else return eval(expr2) } Для данной функции нельзя было выбрать if, поскольку это ключевое слово. Потому было взято наиболее близкое к нему. Обратите внимание: предпо лагается, что выражения передаются функции как строки, содержащие выраже ния. Однако допустимы значения и других типов.

Оператор определения типа Этот оператор используется для проверки, относится ли значение к одному из следующих типов: string, number, boolean, function или undefined. Значение, возвращаемое оператором typeof, является строковым. Оно содержит одно из пе речисленных выше названий типа. Единственный операнд пишется справа от клю чевого слова typeof.

Примеры var x п = N = new s = "Привет a Array(l, 2, 3, 4, 5) function typeof x typeof n '"number" typeof N typeof s typeof a typeof f // 1.10. Приоритеты операторов Выше мы уже говорили, что в выражениях операторы выполняются в порядке, определяемом с помощью круглых скобок, согласно приоритетам;

операторы с одинаковыми приоритетами выполняются слева направо. В этом разделе мы уточним приоритеты всех операторов (табл. 1.6).

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

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

Приоритеты операторов На втором месте по приоритету находится вычисление индексов массивов и оп ределения самих элементов массивов. Индексы массивов, как известно, заключе ны в квадратные скобки.

На последнем месте находится запятая, как разделитель параметров.

Таблица 1.6. Распределение операторов по приоритетам Приоритет Оператор Комментарий ! От внутренних к внешним О Значение индекса массива function() Вызов функции Логическое «не» Побитовое «не» Отрицание Инкремент (приращение) Декремент new typeof void delete Удаление объектного элемента Умножение Деление Деление по модулю (остаток от деления) Сложение (конкатенация).

Вычитание • Побитовые сдвиги Меньше Не больше (меньше или равно) Больше Не меньше (больше или равно) Равенство Неравенство В & Побитовое «и» 9 Побитовое исключающее «или» Побитовое «или» (дизъюнкция) !1 && Логическое «и» (конъюнкция) 12 Логическое «или» продолжение 108 Глава 1. Основы JavaScript Таблица 1.6 (продолжение) Приоритет Оператор Комментарий 13 ? Условное выражение (оператор условия) 14 = Операторы присвоения = Запятая (разделитель параметров) Кроме приоритетов следует также учитывать, что сложные логические выраже ния, состоящие из нескольких более простых, соединенных операторами И и ИЛИ, выполняются по так называемому принципу короткой обработки. Это означает, что значение всего выражения бывает можно определить, вычислив лишь одно или несколько более простых выражений, не вычисляя остальные. Например, выражение х&&у вычисляется слева направо;

если значение х оказалось равным false, то значение у не вычисляется, поскольку и так известно, что значение всего выражения равно false. Аналогично, если в выражении х || у значение х равно true, то значение у не вычисляется, поскольку уже ясно, что все выраже ние равно true.

ВНИМАНИЕ Если вы хотите проверить правильность сложного логического выражения, то необходимо проверить отдельно все его составные части. Если какая-нибудь составная часть выраже ния содержит ошибку, то она может остаться невыявленной, поскольку эта часть выраже ния просто не выполнялась при тестировании.

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

1.11. Зарезервированные ключевые слова Слово interface является ключевым — и, следовательно, его нельзя в качестве имени пользовательского объекта или функции. Однако можно при менить некоторую модификацию этого слова: myinterface, и т. п.

ВНИМАНИЕ Использование символов в различном регистре часто приводит к недоразумениям, обус ловленным тем, что одна и та же по вашему замыслу переменная из-за небрежности встре чается в программе в различном регистре. Поскольку JavaScript является языком, он воспринимает эти переменные как различные.

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

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

Таблица 1.7. Список ключевых слов

Abstract

else super boolean extends interface switch break false long synchronized byte final native this case finally new throw catch float null throws char for package transient class function private true const goto protected continue if public typeof default Implements reset var delete import return void do in short while double instanceof static with Глава 2. Основы создания сценариев В главе мы начнем с краткой истории программирования, а затем рассмот рим основные понятия, объекты JavaScript и приемы работы с ними. Их нужно освоить, прежде чем заниматься более узкими задачами. В главе 4 вы познакоми тесь с конкретными примерами сценариев, но чтобы научиться решать задачи, выходящие за рамки конкретных примеров, прочитайте данную главу. В этом слу чае вы с легкостью и с интересом усвоите справочный материал, изложенный в главе 3.

2.1. Из истории программирования Давным-давно, примерно с 1950 по год, в программировании не было сколь ко-нибудь явно выраженных технологий. Не существовало понятия вызова функ ции, данные хранились где попало, для управления вычислительным процессом широко использовались операторы перехода, в том числе и оператор GO TO (пе рейти туда, я сказал). Программные коды были огромными, содержали мас су ошибок и стоили очень дорого. Операторы GO TO бросали читателя исходных текстов то вверх, то вниз по листингу исходного текста программы. Отладка про грамм занимала львиную долю всего времени разработки. Тогда программирова ли в цифровых кодах команд, а переход к языку мнемокодов Assembler казался этапом значительной автоматизации работы программистов. Нормой производи тельности труда программистов было 3-5 команд в день. В действительности про граммист за месяц писал тысячи кодов, хотя результат состоял всего лишь из не скольких их десятков. А зачем он это делал, если ему платили по норме? В те романтические программистом мог быть только по вычислитель ной технике. При этом программисты, как правило, были еще и математиками.

Математиками их называли до середины 80-х годов прошлого века независимо от того, имели они специальное образование или нет, понимали ли они хоть что нибудь в этой изящной и прекрасной науке или нет.

В период с 1960 по 1975 год появились первые функциональные языки програм мирования, такие как FORTRAN и ALGOL. Эти языки в основном предназнача лись для поддержки формульных вычислений, необходимых ученым и инжене рам. Расчет траекторий орбит космических аппаратов и планет, создание программ наведения антенн, прогноз погоды и параметров электронных схем — далеко не 2.1. Из истории программирования полный перечень задач, обслуживаемых программными языками данного типа.

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

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

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

Методы объекта описывают его поведение. Например, разрабатывая компьютер ную игру, программист может создавать объекты для всех ее персонажей. Кроме статических характеристик (имя, внешний вид, координаты положения), объект может содержать и описания методов изменения положения, своего внешнего вида и реакции на действия игрока. Другими словами, объект представляет собой не кий контейнер, содержащий переменные функции, которые применительно к объекту называются его свойствами и методами. Замечательно еще и то, что в языках, поддерживающих ООП, из одних объектов можно делать другие, до бавляя к ним новые свойства. При этом созданные таким образом новые объекты наследуют свойства исходных (родительских) объектов. Например, объект Сту дент наследует свойства объекта Человек, а последний наследует свойства объекта Млекопитающее. Благодаря механизму наследования программист освобождается от необходимости повторять историю создания новых начиная от Адама.

Самый известный и широко используемый язык ООП — C++. Язык С (просто Си) — мощный, но низкоуровневый язык программирования. В нем есть все не обходимое для создания объектов, однако ответственность за это полностью ло жится на программиста. Язык C++, напротив, большую часть рутинной работы по созданию объектов (классов) берет на себя. Существуют и другие объектно ориентированные языки (например, Java и Object Pascal), но C++ стал стандар том ООП-языка де-факто. Если какой-либо язык так или иначе поддерживает то 112 Глава 2. Основы создания сценариев же, что и C++, то что это ООП-язык. Однако не все языки, поддержива ющие работу с объектами, являются ООП-языками в полной мере. Это, по суще ству, означает, что они поддерживают не все механизмы работы с объектами, ко торые имеются в C++. Так, например, JavaScript не вполне ООП-язык, поскольку его последняя версия 1.5 не поддерживает концепцию наследования свойств объ ектов в том объеме, в каком это реализовано в C++. Заметим при этом, что следу ющая версия JavaScript, как ожидается, уже будет полностью соответствовать концепции ООП.

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

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

В связи с появлением многозадачных операционных систем, таких как Windows, OS/2, Unix и Linux, открылись возможности для так называемого событийного программирования. Программные единицы (объекты, в частности) могут реаги ровать на действия пользователя (например, щелчок кнопкой мыши, нажатие на клавишу и др.), а также передавать сообщения о событиях другим программным единицам. При этом внешне ситуация выглядит так, будто одновременно функ ционирует множество объектов, в какой-то степени автономных, но действующих 2.2. От простого до динамического согласованно, С одной стороны, это открывает огромные воз можности довольно легко создавать интересные и сложные программы. С другой стороны, при необдуманных решениях могут возникнуть непредвиденные и пло хо контролируемые ситуации.

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

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

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

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

Несмотря на похожие названия, между JavaScript и Java очень мало общего. Java похож на C++, но, в отличие от него, является не зависимым от платформы среды выполнения.

2.2. От простого до динамического HTML 2.2.1. Простой HTML Для создания веб-страниц разработан довольно простой язык HTML (Hyper Text Markup Language — язык разметки гипертекста). Изначально он задумывался как язык разметки документа, содержащего текстовую и графическую информацию вместе с элементами управления, такими как ссылки на другие документы. Тек сты, содержащие элементы, которые являются ссылками на другие назы ваются гипертекстами, а сами ссылки называют еще гиперссылками. Кроме тексто вой и графической информации, а также ссылок в документ можно включать аудио и видеофрагменты. Чтобы создать такой документ, достаточно в обычном текстовом редакторе (например, в Блокноте Windows) написать программу на языке HTML Такие программы сохраняются в файлах с расширением htm или html, а выполняют ся они в веб-браузере, например Microsoft Internet Explorer или Netscape Navigator.

Инструкции HTML называют тегами, или дескрипторами. Они выделяются уг ловыми скобками (< и >). Каждый тег имеет свое название, являющееся ключе 114 Глава 2. Основы создания сценариев словом. Спецификация тега обеспечивается его параметрами, которые обыч но называют атрибутами. Атрибуты могут иметь значения (аргументы). Назва ния тегов и атрибуты можно писать в любом регистре. Атрибуты, если они име ются, пишутся за названием тега в произвольном порядке через пробел. Формат тега имеет следующий вид:

[АТРИБУТ1 [=... [= Квадратные скобки показывают, что заключенные в них элементы не обязатель ны. Существуют теги без атрибутов (например, тег перехода на новую строку
), а также атрибуты без аргументов (например, NORESIZE в теге Даже если для тега предусмотрены атрибуты, во многих случаях их можно не указывать, ис пользуя значение по умолчанию. Так, тег SRC = дает браузеру команду вывести на экран графический объект из файла Здесь ключе вое слово — название SRC — атрибут, a "picture.jpg" — аргумент (значе ние). Атрибут ID присущ любому тегу, но если он не используется, то по умолча нию принимается, что его значение — пустая строка.

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

Большинство тегов являются контейнерными. Это означает следующее.

• Тегу <ТЕГ.> обязательно соответствует заключительный тег .

• Между этими тегами можно разместить другие теги, контейнерные или нет.

В связи с этим можно говорить о вложенности одних тегов в другие.

Например, теги тела документа , ссылки <А...>, раздела

, таблицы и др. являются контейнерными, то есть им соответствуют заключитель ные теги ,, , Говоря «внутри тега мы имеем в виду то, что расположено между тегами <ТЕГ> и . В приведенном ниже при мере показано, что внутри тега ссылки <А> можно разместить тег графического изображения , создав таким образом графическую ссылку:

<А HREF = SRC HTML-программа (HTML-код), формирующая документ, начинается тегом и заканчивается тегом Таким образом, является контейнерным тегом, причем самого верхнего уровня.

В HTML-коде существуют теги, которые никак не проявляются в окне браузе ра какими бы то ни было визуальными эффектами (например, , . Встречая тег указыва ет браузеру, что код сценария закончился. Все, что находится вне этих тегов, браузер воспринимает как HTML-код. Контейнер , а все, что находится между ними, интерпретируют как содержимое HTML-документа. Результат может быть самым неожиданным. Чтобы уменьшить вероятность отображения кода сценария в окне старого браузера, следует заклю чить его в дескрипторы комментария

Если сценарий располагается в отдельном файле, то в нем, разумеется, теги не пишутся. Как уже отмечалось, файлы со сценариями на JavaScript являются обычными текстовыми файлами. В принципе, они могут иметь любое расширение имени, но, как правило, используется расширение js. В отдельных файлах обычно размещают библиотеки функций (определения функций), а так же сценарии, использующиеся в нескольких HTML-документах одного или не скольких сайтов. Сценарий, загруженный из внешнего файла, можно представить себе просто как его вставку в HTML-документ. Вот пример:

... function myfuncO...

} 120 Глава 2. Основы создания сценариев При попытке загрузить и выполнить неправильный вариант HTML-кода появит ся диалоговое окно с сообщением об ошибке «Ошибка: Предполагается наличие объ екта». Браузер интерпретирует HTML-теги последовательно. Так, встретив выра жение вызова функции в одном контейнере Если необходимо, чтобы сценарий загрузился в браузер прежде, чем загрузятся элементы HTML-документа, то его следует расположить в верхней части HTML кода. В этом случае сценарий обычно располагают в контейнере (в заго ловке документа). Это самое лучшее место для расположения функций.

Если требуется, чтобы сценарий загрузился загрузки всех элементов HTML документа, то следующие два варианта. Во-первых, можно расположить сценарий в конце Во-вторых, можно использовать атрибут-собы тие onload в контейнерном теге , который задает основную часть мента. В последнем случае значением атрибута onload обычно является строка, со держащая имя функции. Определение этой функции, как правило, содержится в контейнере

событие происходит, когда указатель мыши помещается на элемент HTML-документа. Список событий мы рас смотрим позже. Значением таких атрибутов-событий в тегах HTML является стро ка, содержащая сценарий, выполняющий роль обработчика события. Например, сле дующий HTML-код определяет заголовок второго уровня, который реагирует на щелчок кнопкой мыши тем, что выполняет некоторую функцию <Н2 onclick = здесь Для одного и того же элемента можно определить несколько событий, на которые он будет реагировать. Другими словами, для одного и того же тега можно указать несколько атрибутов-событий. Имена этих атрибутов, как и других, можно пи сать в любом регистре. Порядок следования атрибутов не имеет значения.

Итак, значением атрибута-события, как уже отмечалось, является код сценария, заключенный в кавычки. Этот сценарий называют также обработчиком события.

В приведенном выше примере обработчиком события onclick является функция myfuncQ. Если обработчик события содержит несколько выражений, то они раз деляются точкой с запятой.

<ТЕГ <ТЕГ <ТЕГ Рис. 2.2. Различные варианты оформления обработчиков событий 122 Глава 2. Основы создания сценариев Пример <Н2 onclick = x = 5;

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

1. Изображение в HTML-документе определяется, как известно, тегом .

Файл с изображением задается атрибутом SRC. Обработчик события onclick за дается в примере как функция которая должна быть определена где-то в контейнере Вариант 2:

Чтобы указать браузеру явным образом, что сценарий написан на языке Java Script, можно в значении атрибута-события написать префикс На пример,

Листинг 2.2. Тестируемый код с добавлением атрибутов ID <Н1>Моя веб-страница ID = onclick = продолжение Глава 2. Основы создания сценариев Листинг 2.2 (продолжение) Моя Web-страница Сайт 7 id PUT I Рис. 2.6. Теги HTML-документа, их индексы в коллекции а также значения атрибутов ID Итак, универсальный способ обращения к объекту документа базируется на ис пользовании коллекции Однако кроме него в IE5+ и существует еще один способ, основанный на методе Обратите внимание, в каком регистре пишутся отдельные буквы этого метода.

Метод позволяет обратиться к любому элементу по значению его идентификатора — значению атрибута ID. Если несколько элемен тов документа имеют одинаковый ID, метод возвращает первый элемент с указан ным значением ID. Отсюда видно, насколько важно присваивать различным эле ментам уникальные значения ID.

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

2.4. Понятие события В приведенном выше примере элемент изображения, созданный с помощью тега

// "myimage" var x = // объект // "myimage". src /* строка URL, например, f */ var x = // объект /* строка например, Объекты документа имеют много интересных и полезных свойств. Одни из них доступны только для чтения и могут использоваться в сценариях в качестве ин формации для выполнения каких-то действий. Другие свойства можно изменять, то есть присваивать им иные значения (например, для изменения рисунка доста точно изменить значение свойства src). В следующей главе мы рассмотрим, для чего служат конкретные свойства и методы.

2.4. Понятие события Каждое действие пользователя (нажатие на клавишу, щелчок кнопкой мыши и т. п.) формирует некоторое событие, то есть сообщение о произошедшем. Опе рационная система (например, Windows) анализирует это сообщение, чтобы уз нать, откуда оно взялось и что с ним делать дальше. Если, например, пользователь нажал на кнопку мыши в момент, когда ее указатель находился над окном браузе ра, то Windows пошлет браузеру сообщение о том, какая кнопка мыши была на жата, какие при этом клавиши клавиатуры удерживаются, а также координаты указателя мыши. Если пользователь щелкнул где-то на панели инструментов, браузер отработает это сообщение сам. Если же в момент щелчка указатель нахо дился на «территории» HTML-документа, то браузер пропустит сообщение о со бытии через свою объектную модель. В HTML-коде документа может находиться сценарий для обработки этого события. Инструкции этого сценария направляют ся к браузеру опять же через объектную модель.

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

Глава 2. Основы создания сценариев Объект события хранится в памяти столько времени, сколько необходимо сцена рию для его обработки. Пока выполняется обработчик события, объект события вместе со своими свойствами доступен сценарию, находящемуся в памяти брау зера. Как только обработчик события завершит работу, объект события становит ся пустым (возвращается в исходное состояние).

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

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

В качестве примера ниже приводится HTML-документ, не содержащий видимых элементов. Щелчок мышью или нажатие клавиши на клавиатуре выводит диало говое окно со значениями некоторых свойств объекта event (рис. 2.7). Так, свой ства х и у содержат значения координат указателя мыши в момент щелчка, от в данном случае относительно окна браузера. Свойство keyCode возвращает код нажатой клавиши с символам в системе Unicode. Для латинских и цифровых символов кодировки Unicode и ASCII совпадают. При нажатии навигационных кла виш и клавиш дополнительной цифровой клавиатуры keyCode возвращает null. По существу, keyCode — это код соответствующего символа, а не код клавиши. Для фик сации самой клавиши используются события onkeydown и onkeyup, а не on keypress.

Рис. 2.7. Щелчок в окне браузера выводит сообщение о координатах указателя мыши и нажатой клавише В IE версии 4.0 и старше среди прочих часто оказываются полезными свойства button и srcElement.

Свойство button возвращает целочисленное значение, указывающее, какая кноп ка или кнопки мыши были нажаты (табл. 2.1).

Таблица 2.1. Значения свойства button Значение Описание Кнопки не нажаты 1 Нажата левая ? Нажата правая Одновременно нажаты левая и правая 4 Нажата средняя 5 Нажаты левая и средняя Нажаты правая и средняя 7 Все три кнопки нажаты Свойство srcElement возвращает ссылку на объект элемента HTML-документа, кото рый инициировал событие. При получении такой ссылки можно узнать или изме нить значения свойств этого объекта и применить к нему любой из его методов.

Приведенный ниже HTML-код формирует документ, содержащий две кнопки (рис. 2.8). Сценарий обрабатывает событие — щелчок мышью. Он привя зан к элементу, заданному тегом . Щелкнуть можно на любой кнопке, а так же на незанятом месте окна браузера (рис. 2.9). В любом случае событие onclick будет обработано сценарием (функцией поскольку кнопки заданы внутри тега Сценарий заменит текст, который находится внутри тега эле мента, инициировавшего событие. Какой именно элемент инициировал событие, определяется с помощью свойства srcElement, а замена текста осуществляется по средством свойства innerText. Об этом свойстве мы еще поговорим отдельно. Об ратите внимание, что результат зависит от того, где находился указатель мыши в момент щелчка.

134 Глава 2. Основы создания сценариев -.... • • Рис. 2.8. Результат щелчка на второй кнопке - | ' Уже нажали Рис. 2.9. Результат щелчка на свободном месте Чтобы на щелчок реагировали только кнопки, приведенный выше код необходи мо несколько модифицировать:

onclick =

© 2011 www.dissers.ru - «Бесплатная электронная библиотека»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.