JavaScript и Java
JavaScript и Java похожи друг на друга, но имеют и фундаментальные отличия. Язык JavaScript похож на Java, не не имеет статической типизации Java и строгой проверки типов. JavaScript поддерживает большую часть расширений синтаксиса Java и базовых конструкций управления потоком.
В отличие от системы времени компиляции классов Java, построенной на объявлениях, JavaScript поддерживает систему времени выполнения на базе небольшого количества типов данных: числовых, Булевых и строковых значений. JavaScript имеет объектную модель на базе прототипов, а не на более привычной базе классов. Модель на базе прототипов предоставляет динамическое наследование; то есть то, что наследуется, может отличаться для каждого конкретного объекта. JavaScript также поддерживает функции без каких-либо требований к их объявлению. Функции могут быть свойствами объекта, выполняя свободно типизированные методы.
JavaScript является очень свободным языком по сравнению с Java. Вы не должны объявлять все переменные, классы и методы. Вы не должны заботиться о том, какие методы являются public, private или protected, и не должны реализовывать интерфейсы. Значения, возвращаемые переменными, параметрами и функциями, не типизированные явно.
Java является языком программирования на базе классов, разработанным для быстрого выполнения и безопасности типов. Безопасность типов означает, к примеру, что Вы не можете привести Java integer к ссылке на объект или получить доступ к private-памяти, нарушив байтовый код Java. Модель Java на базе классов означает, что программы состоят исключительно из классов и их методов. Наследование классов Java и строгая типизация в целом требуют тесно связанной иерархии объектов. Эти требования делают язык Java более сложным, чем JavaScript.
В противоположность этому, JavaScript по духу и сути ведёт своё происхождение от линии компактных, динамически типизируемых языков, таких как HyperTalk и dBASE. Эти языки скриптинга предоставляют утилиты программирования для более широкой аудитории, поскольку имеют упрощённый синтаксис, специализированную встроенную функциональность и минимальные требования при создании объектов.
Java
Дополнительную информацию об различиях между JavaScript и Java см. в .
JavaScript и Спецификация ECMA
Netscape изобрела JavaScript, и JavaScript был впервые использован в браузерах фирмы Netscape. Но Netscape работает совместно с (European Computer Manufacturers Association/Европейская Ассоциация Производителей Компьютеров) для создания стандартизованного международного языка программирования на базе ядра JavaScript. ECMA является ассоциацией международных стандартов в области информации и систем коммуникации. Стандартизованная версия JavaScript, называемая ECMAScript, ведёт себя совершенно одинаково во всех приложениях, поддерживающих этот стандарт. Компании могут использовать этот открытый стандартный язык для разработки своих реализаций JavaScript. Первая версия стандарта ECMA задокументирована в спецификации ECMA-262.
Стандарт ECMA-262 также одобрен (International Organization for Standards) как ISO-16262. Вы можете найти на web-сайте Mozilla. Вы можете также найти эту . DOM определяет способ, которым объекты HTML-документа экспонируются в Вашем скрипте.
JavaScript и Терминология ECMA
В спецификации ECMA используется терминология и синтаксис, которые могут быть незнакомы JavaScript-программисту. Хотя описание языка в ECMA может отличаться, сам язык остаётся тем же самым. JavaScript поддерживает всю функциональность спецификации ECMA.
В документации JavaScript описаны аспекты языка, которые нужны программисту на JavaScript. Например:
Объект global не обсуждается в документации по JavaScript, поскольку Вы не используете его явно. Методы и свойства объекта global обсуждаются в документации по JavaScript, но называются функциями и свойствами верхнего уровня.
Конструктор без параметров (нулевой аргумент) с объектами Number и String не обсуждается в документации JavaScript, поскольку то, что генерируется, используется мало. Конструктор объекта Number без аргумента возвращает +0, а конструктор объекта String без аргумента возвращает "" (пустую строку).
Языки на Базе Классов и Языки на Базе Прототипов
Объектно-ориентированные языки на базе классов, такие как Java и C++, основаны на концепции двух различных сущностей: классов и экземпляров.
Класс определяет все свойства (если рассматривать методы и поля Java или члены C++ как свойства), которые характеризуют определённый набор объектов. Класс это абстракция, а не какой-то определённый член набора объектов, которые он описывает. Например, класс Employee может представлять набор всех служащих/employees.
Экземпляр, с другой стороны, это инстанциация класса; то есть один из его членов. Например, Victoria может быть экземпляром класса Employee, представляя отдельного индивидуума как служащего/employee. Экземпляр имеет в точности те свойства, которые имеет его родительский класс (ни больше, ни меньше).
Язык на базе прототипов, такой как JavaScript, не имеет таких различий: в нем просто имеются объекты. Язык на базе прототипов содержит понятие prototypical object\прототипичный объект - объект, используемый как шаблон, из которого получаются начальные свойства для нового объекта. Любой объект может специфицировать свои собственные свойства, либо когда Вы создаёте его, либо на этапе прогона. Кроме того, любой объект может быть ассоциирован как прототип для другого объекта, давая другому объекту возможность использовать свойства первого объекта.
Комментарии обычно
Комментарии обычно разъясняют действия, выполняемые кодом. Комментарии игнорируются интерпретатором. JavaScript поддерживает комментарии в стиле Java и C++:
Однострочный комментарий с двойным слэшем в начале строки (//).
Многострочный комментарий с символами /* в начале и с символами */ в конце.
Пример.
Вот пример двух комментариев:
// Это однострочный комментарий.
/* А это - многострочный. Он может быть любой длины, и Вы можете
поместить сюда всё, что угодно. */
Константы
Вы можете создавать именованные константы "только-для-чтения" с помощью ключевого слова const. Синтаксис идентификатора константы такой же, что и у идентификатора переменной: он обязан начинаться с буквы или символа подчёркивания и может содержать символы алфавита, числа и символ подчёркивания.
const prefix = '212';
Константа не может изменить значение путём нового присвоения и не может быть переобъявлена в процессе выполнения скрипта.
Правила видимости для констант те же, что и для переменных, за исключением того, что ключевое слово const необходимо всегда, даже для глобальных констант. Если ключевое слово отсутствует, идентификатор представляет var.
Вы не можете объявить константу с тем же именем, что и у функции или переменной, в одной области видимости с этой функцией или переменной. Например:
//ЭТО ВЫЗОВЕТ ОШИБКУ
function f{};
const f = 5;
//ЭТО ТАКЖЕ ВЫЗОВЕТ ОШИБКУ
function f{
const g=5;
var g;
//операторы
}
Конверсия Типов Данных
JavaScript это динамически типизированный язык. Это означает, что Вы не должны специфицировать тип данных переменной при её объявлении и что типы данных при необходимости автоматически конвертируются в процессе выполнения скрипта. Так, например, Вы можете определить переменную:
var answer = 42
и позднее можете присвоить этой же переменной строковое значение:
answer = "Thanks for all the fish..."
Поскольку JavaScript типизируется динамически, такое присвоение не является ошибкой.
В выражениях, содержащих числа и строки и операцию +, JavaScript конвертирует числа в строки. Например:
x = "The answer is " + 42 // возвращает "The answer is 42"
y = 42 + " is the answer" // возвращает "42 is the answer"
В выражениях с использованием других операций, JavaScript не конвертирует числа в строки. Например:
"37" - 7 // возвращает 30
"37" + 7 // возвращает 377
Конвертация из Java в JavaScript
Значения, передаваемые из Java в JavaScript, конвертируются так:
Java-значения byte, char, short, int, long, float и double конвертируются в числа JavaScript.
Булево значение Java конвертируется в булево значение JavaScript.
Объект класса netscape.javascript.JSObject конвертируется в оригинальный JavaScript-объект.
Массивы Java конвертируются в объект псевдо-Array JavaScript; поведение этого объекта похоже на объект Array из JavaScript: Вы можете получить к нему доступ через синтаксис arrayName[index] (где index это целое число) и определить его размер через свойство arrayName.length.
Java-объект любого иного класса конвертируется в оболочку JavaScript, которая может использоваться для доступа к методам и полям Java-объекта:
Конвертация этой оболочки в строку вызывает метод toString объекта-оригинала.
Конвертация в число вызывает метод doubleValue, если это возможно, иначе - терпит неудачу.
Конвертация в boolean в JavaScript 1.3 и более поздних версиях возвращает false, если объект - null, и true - в ином случае.
Конвертация в boolean в JavaScript 1.2 и более ранних версиях вызывает метод booleanValue, если это возможно, иначе - терпит неудачу.
Заметьте, что экземпляры объектов java.lang.Double и java.lang.Integer конвертируются в объекты JavaScript, а не в числа JavaScript. Аналогично и экземпляры java.lang.String также конвертируются в объекты JavaScript, а не в строки JavaScript.
Java String-объекты также соответствуют JavaScript-оболочкам. Если Вы вызываете метод JavaScript, который требует строки JavaScript, и передаёте его этой оболочке, Вы получите ошибку. Вместо этого конвертируйте оболочку в строку JavaScript путём присоединения к ней пустой строки, как показано здесь:
var JavaString = JavaObj.methodThatReturnsAString();
var JavaScriptString = JavaString + "";
Copyright © 2000 Все Права Зарезервированы.
Дата последнего обновления 28 сентября 2000 года.
Конвертация JavaScript в Java
Если Вы вызываете Java-метод и передаёте ему параметры из JavaScript, типы данных передаваемых параметров конвертируются в соответствии с правилами, описанными в следующих разделах:
return-значения методов объекта netscape.javascript.JSObject всегда конвертируются в экземпляры объекта java.lang.Object. Правила конвертации этих return-значений также описаны в этих разделах.
Например, если JSObject.eval возвращает JavaScript-число, Вы можете найти правила конвертации этого числа в экземпляр объекта java.lang.Object в разделе .
Конвертация Типов Данных
Поскольку язык Java строго типизирован, а JavaScript типизирован слабо, машина выполнения JavaScript конвертирует значения аргументов в типы данных, подходящие для других языков, если Вы используете LiveConnect. Эта конвертация описана в разделах:
Литералы
Для представления значения в JavaScript можно использовать литералы. Они являются фиксированными значениями, не переменными, которые Вы
литерально\буквально предоставляете в Вашем скрипте.
В этом разделе описаны следующие типы литералов:
Литералы Массива
Литерал массива это заключённый в квадратные скобки ([]) список из нуль или более выражений, каждое из которых представляет элемент массива. Если Вы создаёте массив с использованием литерала массива, этот массив инициализируется специфицированными значениями в качестве элементов, и его размер равен количеству специфицированных аргументов.
В следующем примере создаётся массив coffees из трёх элементов размером "три":
coffees = ["French Roast", "Columbian", "Kona"]
Примечание
Литерал массива это тип инициализатора объекта. См. .
Если массив в скрипте верхнего уровня создаётся с использованием литерала, JavaScript интерпретирует этот массив всякий раз, когда вычисляется выражение, содержащее литерал массива. Кроме того, литерал, используемый в функции, создаётся при каждом вызове функции.
Литералы массива являются также Array-объектами. См. в разделе детали об Array-объектах.
Дополнительные запятые в литералах массивов
Вам не нужно специфицировать все элементы в литерале массива. Если Вы поместите две запятые в литерал, массив будет создан с пространством для unspecified(неспецифицированных)-элементов.
В следующем примере создаётся массив fish:
fish = ["Lion", , "Angel"]
В этом массиве имеются два элемента со значениями и один пустой элемент (fish[0] это "Lion", fish[1] - undefined и fish[2] - "Angel").
Если Вы вставите запятую в конце списка элементов, она игнорируется. В следующем примере размер массива - "три". Элемента myList[3] нет. Две другие запятые в списке обозначают новый элемент.
myList = ['home', , 'school', ];
В следующем примере размер массива - "четыре", а myList[0] и myList[2] пропущены.
myList = [ , 'home', , 'school'];
В следующем примере размер массива - "четыре", а myList[1] и myList[3] пропущены. Игнорируется только последняя запятая. Эта ведомая запятая не обязательна.
myList = ['home', , 'school', , ];
Литералы Объектов
Литерал объекта это заключённый в фигурные скобки ({}) список из 0 или более пар свойств объекта и ассоциированных с ними значений. Вы не должны использовать литерал объекта в начале оператора. Это приведёт к ошибке, или поведение будет не таким, какое Вы ожидаете, поскольку { будет интерпретироваться как начало блока.
Вот пример литерала объекта. Первый элемент объекта car определяет свойство myCar; второй элемент - свойство getCar, вызывающее функцию (CarTypes("Honda")); третий элемент, специальное свойство, использует существующие переменные (Sales).
var Sales = "Toyota";
function CarTypes(name) {
if(name == "Honda")
return name;
else
return "Sorry, we don't sell " + name + ".";
}
car = {myCar: "Saturn", getCar: CarTypes("Honda"), special: Sales}
document.write(car.myCar); // Saturn
document.write(car.getCar); // Honda
document.write(car.special); // Toyota
Вы можете использовать числовой или строковой литерал для именования свойства или вложения одного объекта в другой. Следующий пример использует эти опции:
car = {manyCars: {a: "Saab", b: "Jeep"}, 7: "Mazda"}
document.write(car.manyCars.b); // Jeep
document.write(car[7]); // Mazda
Литералы с Плавающей Точкой
Литерал с плавающей точкой может состоять из следующих частей:
10-ричного целого числа
Десятичной точки (".")
Дробной части (другого 10-ричного числа)
Экспоненты
Экспонентная часть это "e" или "E" и последующее целое число, которое может иметь знак ("+" или "-"). Литерал с плавающей точкой обязан иметь как минимум одну цифру и десятичную точку или "e" (или "E").
Примеры литералов с плавающей точкой: 3.1415, -3.1E12, .1e12, 2E-12.
Логические Операции
Логические операции обычно используются с Boolean (булевыми/логическими) значениями; в этом случае возвращается Boolean-значение. Однако операции && и реально возвращают значение одного из специфицированных операндов, поэтому, если эти операции используются с не-Boolean-значениями, они могут вернуть не-Boolean значение. Логические операции описаны в следующей таблице.
&&
(Логическое И) Возвращает expr1, если оно может быть конвертировано в false; иначе возвращает expr2. Таким образом, при использовании с Boolean-значениями, && возвращает true, если оба операнда true; иначе возвращает false.
(Логическое ИЛИ) Возвращает expr1, если оно может быть конвертировано в true; иначе возвращает expr2. Таким образом, при использовании с Boolean-значениями, возвращает true, если хотя бы один из операндов true; если оба операнда false, возвращает false.
Примерами выражений, которые могут быть конвертированы в false являются такие выражения, которые вычисляются в null, 0, пустую строку ("") или undefined.
Вот примеры операции && (логическое И):
a1=true && true // t && t возвращает true
a2=true && false // t && f возвращает false
a3=false && true // f && t возвращает false
a4=false && (3 == 4) // f && f возвращает false
a5="Cat" && "Dog" // t && t возвращает Dog
a6=false && "Cat" // f && t возвращает false
a7="Cat" && false // t && f возвращает false
Примеры операции (логическое ИЛИ):
o1= true true // t t возвращает true
o2=false true // f t возвращает true
o3=true false // t f возвращает true
o4=false (3 == 4) // f f возвращает false
o5="Cat" "Dog" // t t возвращает Cat
o6=false "Cat" // f t возвращает Cat
o7="Cat" false // t f возвращает Cat
Примеры операции ! (логическое НЕ):
n1=!true // !t возвращает false
n2=!false // !f возвращает true
n3=!"Cat" // !t возвращает false
Локальные и Наследуемые Значения
Когда Вы осуществляете доступ к свойству объекта, JavaScript выполняет следующие шаги, как уже было описано в этой главе ранее:
Проверяет, существует ли значение локально. Если так, возвращается это значение.
Если локального значения нет, проверяет цепочку прототипов (используя свойство __proto__).
Если объект в цепочке прототипов имеет значение для специфицированного свойства, возвращается это значение.
Если такое свойство не найдено, объект не имеет этого свойства.
Результат выполнения этих шагов зависит от того, как Вы выполняете определения. Оригинал примера имел такие определения:
function Employee () {
this.name = "";
this.dept = "general";
}
function WorkerBee () {
this.projects = [];
}
WorkerBee.prototype = new Employee;
Имея эти определения, создадим amy как экземпляр объекта WorkerBee следующим оператором:
amy = new WorkerBee;
Объект amy имеет одно локальное свойство, projects. Значения свойств name и dept не являются локальными для amy и поэтому получены из свойства __proto__ объекта amy. Таким образом, amy имеет следующие значения свойств:
amy.name == "";
amy.dept = "general";
amy.projects == [];
Теперь предположим, что Вы изменили значение свойства name в прототипе, ассоциированном с Employee:
Employee.prototype.name = "Unknown"
На первый взгляд, можно ожидать, что новое значение будет распространено на все экземпляры Employee, однако это не так.
Если Вы создаёте любой экземпляр объекта Employee, этот экземпляр получает локальное значение свойства name (пустую строку). Это означает, что, если Вы устанавливаете прототип WorkerBee через создание нового Employee-объекта, WorkerBee.prototype имеет локальное значение для свойства name. Следовательно, когда JavaScript видит свойство name объекта amy (экземпляра WorkerBee), JavaScript находит локальное значение этого свойства в WorkerBee.prototype. Он, следовательно, не просматривает далее цепь Employee.prototype.
Если Вы хотите изменить значение свойства объекта на этапе прогона программы и имеете новое значение, наследуемое всеми потомками объекта, Вы не можете определить это свойство в конструкторе функции объекта. Вместо этого Вы добавляете его к ассоциированному с конструктором прототипу. Например, предположим, Вы изменяете предыдущий код таким образом:
function Employee () {
this.dept = "general";
}
Employee.prototype.name = "";
function WorkerBee () {
this.projects = [];
}
WorkerBee.prototype = new Employee;
amy = new WorkerBee;
Employee.prototype.name = "Unknown";
В этом случае свойство name объекта amy стало "Unknown".
Как показывают все эти примеры, если Вы хотите иметь значения по умолчанию для свойств объекта и иметь возможность изменять эти значения по умолчанию на этапе прогона программы, Вы должны установить свойства прототипа конструктора, а не сам конструктор функции.
Написание Патэрна Регулярного Выражения
Патэрн регулярного выражения состоит из обычных символов, таких как /abc/, или из комбинаций обычных и специальных символов, таких как /ab*c/ или /Chapter (\d+)\.\d*/. В последнем примере есть скобки, которые используются в качестве запоминающего устройства. Совпадение этой части патэрна запоминается для последующего использования, как описано в разделе .
Наследование Свойств
Предположим, Вы создаёте объект mark как экземпляр объекта WorkerBee, как показано на , следующим оператором:
mark = new WorkerBee;
Когда JavaScript встречает оператор new, он создаёт новый общий родовой/generic объект и передаёт этот новый объект как значение ключевого слова this в конструктор функции WorkerBee. Конструктор функции явно устанавливает значение свойства projects. Он также устанавливает значение внутреннего свойства __proto__ в значение WorkerBee.prototype. (Имя этого свойства содержит два символа подчёркивания в начале и два - в конце.)
__proto__ определяет цепь прототипов, используемую для возвращения значений свойств. После того как эти свойства установлены, JavaScript возвращает новый объект, и оператор присвоения устанавливает переменную mark в этот объект.
Этот процесс не помещает явно значения в объект mark (локальные значения) для свойств, которые mark наследует от цепи прототипов. Когда Вы запрашиваете значение свойства, JavaScript сначала проверяет, существует ли значение в этом объекте. Если существует, это значение возвращается. Если локального значения нет, JavaScript проверяет цепь прототипов (используя свойство __proto__). Если объект в цепи прототипов имеет значение для этого свойства, это значение возвращается. Если такое свойство не найдено, JavaScript сообщает, что объект не имеет этого свойства. Таким образом, объект mark имеет следующие свойства и значения:
mark.name = "";
mark.dept = "general";
mark.projects = [];
Объект mark наследует значения свойств name и dept из прототипичного объекта в mark.__proto__. Оно присваивается локальному значению свойства projects конструктором WorkerBee. Это даёт Вам наследование свойств и их значений в JavaScript. Некоторые тонкости этого процесса обсуждаются в разделе .
Поскольку эти конструкторы не позволяют вводить значения, специфичные для экземпляра, эта информация является общей. Значения свойств являются значениями по умолчанию, используемыми всеми новыми объектами, создаваемыми на основе WorkerBee. Вы можете, разумеется, изменять значение любого из этих свойств. Так, Вы можете ввести в mark специфическую информацию:
mark.name = "Doe, Mark";
mark.dept = "admin";
mark.projects = ["navigator"];
Нет Множественного Наследования
Некоторые объектно-ориентированные языки разрешают множественное наследование. То есть, объект может наследовать свойства и значения из не связанных между собой родительских объектов. JavaScript не поддерживает множественное наследование.
Наследование значений свойств возникает на этапе прогона программы, когда JavaScript ищет значение по цепочке прототипов объекта. Поскольку объект имеет единственный ассоциированный прототип, JavaScript не может динамически наследовать из более чем одной цепочки прототипов.
В JavaScript Вы можете иметь несколько вызовов одного конструктора функции внутри другого. Это создаёт иллюзию множественного наследования. Например, рассмотрим следующие операторы:
function Hobbyist (hobby) {
this.hobby = hobby "scuba";
}
function Engineer (name, projs, mach, hobby) {
this.base1 = WorkerBee;
this.base1(name, "engineering", projs);
this.base2 = Hobbyist;
this.base2(hobby);
this.machine = mach "";
}
Engineer.prototype = new WorkerBee;
dennis = new Engineer("Doe, Dennis", ["collabra"], "hugo")
Далее предположим, что имеется определение WorkerBee, такое как ранее в этой главе. В этом случае объект dennis имеет три свойства:
dennis.name == "Doe, Dennis"
dennis.dept == "engineering"
dennis.projects == ["collabra"]
dennis.machine == "hugo"
dennis.hobby == "scuba"
Итак, dennis получает свойство hobby от конструктора Hobbyist. Однако предположим, что Вы затем добавляете свойство в прототип конструктора Hobbyist:
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
Объект dennis не наследует это новое свойство.
Copyright © 2000 Все Права Зарезервированы.
Дата последнего обновления 28 сентября 2000 года.
New
Вы можете использовать операцию new для создания экземпляра объекта пользовательского типа или экземпляра одного из предопределённых типов объекта: Array, Boolean, Date, Function, Image, Number, Object, Option, RegExp или String. На сервере Вы можете также использовать её с DbPool, Lock, File или SendMail. Используйте new так:
objectName = new objectType ( param1 [,param2] ...[,paramN] )
Вы можете также создать объекты, используя инициализаторы объектов, как описано в .
См. new в книге
Новые Возможности Этой Версии
Резюме по нововведениям JavaScript версии 1.5 см. в разделе .
Информация об этих возможностях содержится в статьях данного учебника.
Новые Возможности в Этой Версии
JavaScript версии 1.5 содержит следующие новые возможности и улучшения:
Ошибки времени выполнения. О них теперь сообщается как об исключениях.
Улучшение форматирования чисел. Включены методы Number.prototype.toExponential, Number.protoytpe.toFixed и Number.prototype.toPrecision.
Добавлены следующие улучшения в регулярных выражениях:
Квантификаторы +, *, ? и {} могут иметь теперь после себя ? для форсирования их в нежадные. .
Незахватывающие скобки, (?:x) могут использоваться вместо захватывающих скобок (x). Если используются незахватывающие скобки, совпадающие подвыражения недоступны как обратные ссылки. .
Положительные и отрицательные "смотрящие вперёд утверждения" поддерживаются. И те, и другие подтверждают совпадение, в зависимости от того, что идёт после совпавшей подстроки. .
Флаг m был добавлен, чтобы дать возможность специфицировать, что регулярное выражение должно совпадать на нескольких строках
Объявление условной функции. Функции могут теперь объявляться внутри if.
Функции выражения. Функции могут теперь объявляться внутри выражения.
Несколько переходов catch поддерживаются теперь внутри оператора try...catch.
Getter'ы и Setter'ы. Теперь в JavaScript можно добавлять их к объектам. Эта возможность имеется только в C-реализации JavaScript.
Константы. Теперь поддерживаются именованные константы "только для чтения". Эта возможность имеется только в C-реализации JavaScript.
Copyright © 2000 Все Права Зарезервированы.
Дата последнего обновления 28 сентября 2000 года.
Null-Значения
Если Вы передаёте значения null JavaScript в качестве параметра Java-методам, Java конвертирует значения в соответствии с правилами, описанными в следующей таблице:
Любой класс
Любой тип интерфейса
Значение становится null.
byte
char
double
float
int
long
short
Значение становится 0.
boolean
Значение становится false.
Объект Array
В JavaScript нет отдельного типа для массива данных. Однако Вы можете использовать предопределённый объект Array и его методы для работы с массивами в Ваших приложениях. Объект Array имеет методы для манипулирования массивами: объединения, разворачивания и сортировки. Он имеет также свойство для определения размера массива и другие свойства для использования с регулярными выражениями.
Массив это упорядоченный набор значений, к которым можно обращаться по имени и по индексу. Например, Вы имеете массив emp, содержащий имена служащих, индексированный по именам служащих. Так, emp[1] это служащий номер 1, emp[2] - служащий номер 2 и так далее.
Создание Массива
Чтобы создать Array-объект:
1. arrayObjectName = new Array(element0, element1, ..., elementN)
2. arrayObjectName = new Array(arrayLength)
arrayObjectName это имя нового объекта, либо свойство существующего объекта. При использовании Array-свойств и методов, arrayObjectName это либо имя существующего Array-объекта, либо свойство существующего объекта.
element0, element1, ..., elementN это список значений элементов массива. Когда специфицирована эта форма, массив инициализируется специфицированными значениями в качестве элементов массива, а свойство length массива устанавливается в количество аргументов.
arrayLength это начальный размер массива. Следующий код создаёт массив из 5 элементов:
billingMethod = new Array(5)
Литералы массива также являются Array-объектами; например, нижеследующий литерал является Array-объектом. См. .
coffees = ["French Roast", "Columbian", "Kona"]
Наполнение Массива
Вы можете заполнить массив путём присвоения значений его элементам. Например,
emp[1] = "Casey Jones"
emp[2] = "Phil Lesh"
emp[3] = "August West"
Вы можете также заполнить массив при его создании:
myArray = new Array("Hello", myVar, 3.14159)
Обращение к Элементам Массива
Вы можете обратиться к элементам массива через использование порядкового номера элемента. Например, Вы определили массив:
myArray = new Array("Wind","Rain","Fire")
Затем Вы обращаетесь к первому элементу массива myArray[0], а ко второму элементу - myArray[1].
Индексы элементов начинаются с нуля (0), но размер массива (например, myArray.length) отражает точное количество элементов в массиве.
Array-Методы
Array-объект имеет следующие методы:
concat объединяет два массива и возвращает новый массив;
join объединяет все элементы массива в строку;
pop удаляет последний элемент массива и возвращает этот элемент;
push добавляет один или более элементов в конец массива и возвращает эти последние добавленные элементы;
reverse разворачивает элементы массива: первый элемент становится последним, а последний - первым;
shift удаляет первый элемент массива и и возвращает этот элемент;
slice извлекает часть массива и возвращает новый массив;
splice добавляет и/или удаляет элементы из массива;
sort сортирует элементы массива;
unshift добавляет один или более элементов в начало массива и возвращает новый размер массива.
Например, Вы определили следующий массив:
myArray = new Array("Wind","Rain","Fire")
myArray.join() возвращает "Wind,Rain,Fire";
myArray.reverse переворачивает массив так, что myArray[0] будет "Fire", myArray[1] - "Rain", а myArray[2] - "Wind".
myArray.sort сортирует массив так, что myArray[0] будет "Fire", myArray[1] - "Rain", в myArray[2] - "Wind".
Двухмерные Массивы
Следующий код создаёт двухмерный массив:
a = new Array(4)
for (i=0; i < 4; i++) {
a[i] = new Array(4)
for (j=0; j < 4; j++) {
a[i][j] = "["+i+","+j+"]"
}
}
Создаётся массив, состоящий из следующих рядов/rows:
Row 0:[0,0][0,1][0,2][0,3]
Row 1:[1,0][1,1][1,2][1,3]
Row 2:[2,0][2,1][2,2][2,3]
Row 3:[3,0][3,1][3,2][3,3]
Массивы и Регулярные Выражения
Ели массив является результатом совпадения регулярного выражения и строки, этот массив возвращает свойства и элементы, предоставляющие информацию о совпадении. Массив является return-значением методов RegExp.exec, String.match и String.split. Об использовании массивов с регулярными выражениями см. .
Объект Boolean
Объект Boolean является оболочкой вокруг примитивного типа данных Boolean. Для создания Boolean-объекта используйте следующий синтаксис:
booleanObjectName = new Boolean(value)
Не путайте примитивные Boolean-значения true и false со значениями true и false Boolean-объекта. Любой объект, значение которого не undefined , null, 0, NaN или не пустая строка, включая Boolean-объект со значением false, вычисляется в true при передаче условному оператору. См. .
Объект Date
В JavaScript нет типа данных data. Однако Вы можете использовать для работы с датами и временем объект Date и его методы. Объект Date имеет большое количество методов для установки, получения и манипулирования датами. Он не имеет никаких свойств.
JavaScript обрабатывает даты аналогично Java. Эти два языка имеют много аналогичных date-методов и оба хранят даты как количество миллисекунд, прошедших после 1 января 1970 года, 00:00:00.
Объект Date имеет диапазон значений от -100,000,000 до 100,000,000 дней в обе стороны от 01 января 1970 года UTC (Всемирного Времени).
Для создания Date-объекта:
dateObjectName = new Date([parameters])
где dateObjectName это имя создаваемого Date-объекта; это может быть новый объект или свойство существующего объекта.
Параметры/parameters в этом синтаксисе могут быть:
пустыми: вводятся текущие время и дата. Например, today = new Date();
строкой, представляющей дату в следующем формате: "месяц день, год час:минуты:секунды." Например, Xmas95 = new Date("December 25, 1995 13:30:00"). Если Вы пропустите часы, минуты или секунды, значение будет установлено в нуль.
набором целочисленных значений для года, месяца и дня. Например, Xmas95 = new Date(1995,11,25). Набором значений для года, месяца, дня, часов, минут и секунд. Например, Xmas95 = new Date(1995,11,25,9,30,0).
JavaScript 1.2 и ранее.
Объект Date ведёт себя так:
Даты до 1970 не допускаются.
JavaScript зависит от специфики поведения даты на конкретной платформе; поведение Date-объекта варьируется от платформы к платформе.
Методы Объекта Date
Методы объекта Date для работы с датами и временем подразделяются на следующие категории:
"set" методы для установки значений даты времени в Date-объектах;
"get" методы для получения значений даты времени из Date-объектов;
"to" методы для возвращения строковых значений из Date-объектов;
методы parse и UTC для разбора Date-строк.
С помощью методов "get" и "set" Вы можете по отдельности получать и устанавливать значения секунд, минут, часа, дня месяца, дня недели, месяца и года. Имеется метод getDay, возвращающий день недели, но отсутствует парный метод setDay, поскольку день недели устанавливается автоматически. Эти методы используют целые числа для представления своих значений:
Секунд и минут: от 0 до 59
Часа: от 0 до 23
Дня недели: от 0 (воскресенье) до 6 (суббота)
Даты: от 1 до 31 (день месяца)
Месяца: от 0 (январь) до 11 (декабрь)
Года: годы после 1900
Например, Вы определили следующую дату:
Xmas95 = new Date("December 25, 1995")
Тогда Xmas95.getMonth() возвратит 11, а Xmas95.getFullYear() возвратит 1995.
Методы getTime и setTime используются при сравнении дат. Метод getTime возвращает количество миллисекунд, прошедших после 1 января 1970 года, 00:00:00, для Date-объекта.
Например, следующий код выводит количество дней, оставшихся до конца текущего года:
today = new Date()
endYear = new Date(1995,11,31,23,59,59,999) // Устанавливает день и месяц
endYear.setFullYear(today.getFullYear()) // Устанавливает год в текущее значение
msPerDay = 24 * 60 * 60 * 1000 // Количество миллисекунд в день
daysLeft = (endYear.getTime() - today.getTime()) / msPerDay
daysLeft = Math.round(daysLeft) //возвращает количество оставшихся в этом году дней
Этот пример создаёт Date-объект по имени today, содержащий текущую дату. Затем создаётся Date-объект endYear и в него устанавливается текущее значение года. Затем, путём использования количества миллисекунд в день, вычисляется количество дней от сегодняшнего числа до до endYear через использование метода getTime и оно округляется до целого количества дней.
Метод parse применяется для присвоения значений date-строк существующим Date-объектам. Например, следующий код использует методы parse и setTime для присвоения значения даты объекту IPOdate:
IPOdate = new Date()
IPOdate.setTime(Date.parse("Aug 9, 1995"))
Использование Объекта Date: Пример
В этом примере функция JSClock() возвращает время в формате электронного циферблата:
function JSClock() {
var time = new Date()
var hour = time.getHours()
var minute = time.getMinutes()
var second = time.getSeconds()
var temp = "" + ((hour > 12) ? hour - 12 : hour)
if (hour == 0)
temp = "12";
temp += ((minute < 10) ? ":0" : ":") + minute
temp += ((second < 10) ? ":0" : ":") + second
temp += (hour >= 12) ? " P.M." : " A.M."
return temp
}
Функция JSClock сначала создаёт новый Date-объект time; поскольку аргументы не заданы, time создаётся с текущими датой и временем. Затем вызываются методы getHours, getMinutes и getSeconds, присваивающие текущие значения часа, минут и секунд переменным hour, minute и second.
Следующие 4 оператора строят строковое значение на базе time. Первый оператор создаёт переменную temp, присваивая её значение путём использования условного выражения; если hour больше 12, (hour - 12), иначе просто hour, если только hour не 0, тогда он становится 12.
Следующий оператор присоединяет значение minute к temp. Если значение minute меньше 10, условное выражение прибавляет строку с предшествующим нулём; иначе добавляется строка с разделяющим двоеточием. Затем оператор присоединяет второе значение к temp тем же способом.
Наконец, условное выражение присоединяет "PM" к temp, если hour равен 12 или больше; иначе присоединяется "AM".
Объект Function
Предопределённый объект Function специфицирует строку кода JavaScript, которая компилируется как функция.
Создание Function-объекта:
functionObjectName = new Function ([arg1, arg2, ... argn], functionBody)
functionObjectName это имя переменной или свойства существующего объекта. Это также может быть объект с последующим именем обработчика события, в нижнем регистре, таким как window.onerror.
arg1, arg2, ... argn это аргументы, используемые функцией в качестве имён формальных аргументов. Каждый обязан быть строкой, соответствующей верному идентификатору JavaScript; например, "x" или "theForm".
functionBody это строка, специфицирующая код JavaScript, компилируемый как тело функции.
Function-объекты вычисляются всякий раз при их использовании. Это менее эффективно, чем объявление функции и вызов её в коде, поскольку объявленные функции компилируются.
Дополнительно Вы можете также использовать оператор function и выражение function. См. книгу .
Следующий код присваивает функцию переменной setBGColor. Эта функция устанавливает цвет фона документа.
var setBGColor = new Function("document.bgColor='antiquewhite'")
Чтобы вызвать Function-объект, Вы можете специфицировать имя переменной так, будто это функция. Следующий код выполняет функцию, специфицированную переменной setBGColor:
var colorChoice="antiquewhite"
if (colorChoice=="antiquewhite") {setBGColor()}
Вы можете назначить функцию обработчику события одним из следующих способов:
1. document.form1.colorButton.onclick=setBGColor
2. <INPUT NAME="colorButton" TYPE="button"
VALUE="Change background color"
onClick="setBGColor()">
Создание переменной setBGColor, показанное выше, аналогично объявлению следующей функции:
function setBGColor() {
document.bgColor='antiquewhite'
}
Присвоение функции переменной похоже на объявление функции, но есть и отличия:
Если Вы присваиваете функцию переменной, используя var setBGColor = new Function("..."), setBGColor является переменной, для которой текущим значением является ссылка на функцию, созданную оператором new Function().
Если Вы создаёте функцию, используя function setBGColor() {...}, setBGColor не является переменной. Это имя функции.
Вы можете вложить одну функцию в другую. Вложенная (внутренняя) функция является private для своего контейнера (внешней функции):
Доступ ко внутренней функции имеется только из операторов во внешней функции.
Внутренняя функция может использовать аргументы и переменные внешней функции. Внешняя функция не может использовать аргументы и переменные внутренней функции.
Объект Math
Предопределённый объект Math имеет свойства и объекты для работы с математическими константами и функциями. Например, свойство PI объекта Math имеет значение pi (3.141...), которое Вы можете использовать в приложении таким образом:
Math.PI
Аналогично и стандартные математические функции являются методами объекта Math. Сюда входят тригонометрические, логарифмические, экспоненциальные и другие функции. Например, Если Вы хотите использовать тригонометрическую функцию sine/синус, Вы можете записать:
Math.sin(1.56)
Заметьте, что все тригонометрические методы объекта Math принимают аргументы в радианах.
В таблице содержится резюме по методам объекта Math.
Таблица 7.1   Методы Объекта Math
abs |
Абсолютное значение.
sin, cos, tan
Стандартные тригонометрические функции; аргумент в радианах.
acos, asin, atan, atan2
Инверсные тригонометрические функции; возвращают значения в радианах.
exp, log
Возвращает ближайшее целое число, больше или равное аргументу.
floor
Возвращает наибольшее целое число, меньше или равное аргументу.
min, max
Возвращает больший или меньший (соответственно) из двух аргументов.
pow
Степень; первый аргумент это база, второй показатель степени.
random
Округляет аргумент до ближайшего целого.
В отличие от многих других объектов, объект Math никогда не может быть создан внутри себя. Вы всегда используете предопределённый объект Math.
Объект Number
Объект Number содержит свойства для работы с числовыми константами, такими как максимальное значение, not-a-number и infinity/бесконечность. Вы не можете изменить значения этих свойств и будете использовать их таким образом:
biggestNum = Number.MAX_VALUE
smallestNum = Number.MIN_VALUE
infiniteNum = Number.POSITIVE_INFINITY
negInfiniteNum = Number.NEGATIVE_INFINITY
notANum = Number.NaN
Вы всегда обращаетесь к свойствам предопределённого объекта Number так, как показано выше, а не как к свойствам Number-объекта, созданного Вами.
В таблице дано резюме по свойствам объекта Number.
MAX_VALUE |
Наибольшее представимое число.
Наименьшее представимое число.
Специальное значение "not a number/не число".
NEGATIVE_INFINITY
Специальное значение отрицательной бесконечность; возвращается при переполнении.
Специальное значение положительной бесконечности; возвращается при переполнении.
Прототип Number предоставляет методы для запроса информации от Number-объектов в разных форматах. В следующей таблице дано резюме по методам Number.prototype.
toExponential |
Возвращает строку - число в экспоненциальной нотации.
toFixed
Возвращает строку - число в нотации с плавающей точкой.
toPrecision
Возвращает строку - число специфицированной точности в нотации с плавающей точкой.
toSource
Возвращает литерал объекта - специфицированный Number-объект; Вы можете использовать это значение для создания нового объекта. Переопределяет метод Object.toSource.
Возвращает строку - специфицированный объект. Переопределяет метод Object.toString.
valueOf
Возвращает примитивное значение специфицированного объекта. Переопределяет метод Object.valueOf.
Объект Packages
Если Java-класс не является частью пакетов java, sun или netscape, Вы можете получить к нему доступ через объект Packages. Например, предположим, корпорация Redwood использует Java-пакет под названием redwood как контейнер различных Java-классов. Чтобы создать экземпляр класса HelloWorld из redwood, Вы осуществляете доступ к конструктору класса так:
var red = new Packages.redwood.HelloWorld()
Вы можете также иметь доступ к классам в пакете по умолчанию (то есть к классам, не указывающим пакет явно). Например, если класс HelloWorld находится непосредственно в пути CLASSPATH, а не в пакете, Вы можете получить к нему доступ так:
var red = new Packages.HelloWorld()
Объекты LiveConnect java, sun и netscape являются аббревиатурами для наиболее часто употребляющихся Java-пакетов. Например:
var myString = new java.lang.String("Hello world")
вместо более длинной версии:
var myString = new Packages.java.lang.String("Hello world")
Объект RegExp
Объект RegExp позволяет работать с регулярными выражениями. описан в
Объект String
Объект String является оболочкой вокруг примитивного типа данных string. Не путайте строковой литерал с объектом String. Например, следующий код создаёт строковой литерал s1 и String-объект s2:
s1 = "foo" //создаётся строковое литеральное значение
s2 = new String("foo") //создаётся String-объект
Вы можете вызвать любой из методов объекта String в строковом литеральном значении - JavaScript автоматически конвертирует строковой литерал во временный String-объект, вызывает метод, затем уничтожает временный String-объект. Вы можете также использовать со строковым литералом свойство String.length.
Вы, как правило, должны использовать строковые литералы, если только Вам не нужно использовать именно String-объект, так как String-объекты могут иметь непредсказуемое поведение. Например:
s1 = "2 + 2" //строковое литеральное значение
s2 = new String("2 + 2")//String-объект
eval(s1) //возвращает число 4
eval(s2) //возвращает строку "2 + 2"
Объект String имеет только одно свойство, length, которое обозначает количество символов в строке. Например, следующий код присваивает переменной x значение 13, так как строка "Hello, World!" содержит 13 символов:
myString = "Hello, World!"
x = mystring.length
Объект String имеет методы двух типов: возвращающие варианты самой строки, такие методы как substring и toUpperCase, и методы, которые возвращают HTML-форматированную версию строки, такие методы как bold и link.
Например, используя предыдущий пример, и mystring.toUpperCase(), и "hello, world!".toUpperCase() возвращают строку "HELLO, WORLD!"
Метод substring принимает два аргумента и возвращает подстроку между двумя аргументами. Используя предыдущий пример, mystring.substring(4, 9) возвращает строку "o, Wo". См. метод substring объекта String в книге
.
Объект String имеет также несколько методов для автоматического HTML-форматирования, такие как bold - для создания текста с "жирным" шрифтом и link - для создания гиперссылки. Например, Вы можете создать гиперссылку на гипотетический URL методом link:
mystring.link("http://www.helloworld.com")
В таблице дано резюме по методам String-экземпляров.
anchor |
big, blink, bold,
fixed, italics, small,
strike, sub, sup
charAt, charCodeAt
indexOf, lastIndexOf
substring, substr
match, replace, search
Copyright © 2000 Все Права Зарезервированы.
Дата последнего обновления 28 сентября 2000 года.
Объекты и Свойства
Объект в JavaScript имеет ассоциированные с ним свойства. Вы получаете доступ к свойству очень просто:
объектаИмя.свойстваИмя
И имя объекта, и имя свойства чувствительны к регистру. Вы определяете свойство, присваивая ему значение. Например, предположим, имеется объект myCar (начиная отсюда, примем для удобства, что объект уже существует). Вы можете создать свойства make, model и year таким образом:
myCar.make = "Ford";
myCar.model = "Mustang";
myCar.year = 1969;
Массив является упорядоченным набором значений, ассоциированных с именем одной переменной. Свойства и массивы JavaScript очень тесно связаны; фактически они являются разными интерфейсами для одной и той же структуры данных. Так, например, Вы можете получить доступ к свойствам объекта myCar:
myCar["make"] = "Ford"
myCar["model"] = "Mustang"
myCar["year"] = 1967
Этот тип массива известен как ассоциативный массив, поскольку каждый элемент индекса ассоциирован также со строковым значением. Следующая функция отображает свойства и имя объекта как аргументы функции:
function show_props(obj, obj_name) {
var result = "";
for (var i in obj)
result += obj_name + "." + i + " = " + obj[i] + "\n";
return result
}
Итак, вызов функции show_props(myCar, "myCar") вернёт:
myCar.make = Ford
myCar.model = Mustang
myCar.year = 1967
Объекты JavaArray и JavaObject
В большинстве случаев, если Вы передаёте JavaArray или JavaObject JavaScript в качестве параметра Java-методу, Java просто снимает оболочку с объекта; в некоторых случаях объект приводится к другому типу данных в соответствии с правилами, описанными в следующей таблице:
Любой интерфейс или класс, совместимый при присвоении с развёрнутым /unwrapped объектом.
Объект разворачивается.
java.lang.String
Объект разворачивается, вызывается метод toString развёрнутого Java-объекта, и результат возвращается как новый экземпляр объекта java.lang.String.
byte
char
double
float
int
long
short
Объект разворачивается, и возникает одна из следующих ситуаций:
Если развёрнутый Java-объект имеет метод doubleValue, the JavaArray или JavaObject конвертируется в значение, возвращаемое этим методом.
Если развёрнутый Java-объект не имеет метода doubleValue, возникает ошибка.
boolean
В JavaScript 1.3 и более поздних версиях, объект разворачивается, и возникает одна из следующих ситуаций:
Если объект - null, он конвертируется в false.
Если объект имеет какое-либо другое значение, он конвертируется в true.
В JavaScript 1.2 и ранее, объект разворачивается, и возникает одна из следующих ситуаций:
Если развёрнутый объект имеет метод booleanValue, the исходный объект конвертируется в return-значение.
Если развёрнутый объект не имеет метода booleanValue, конвертация терпит неудачу.
Интерфейс или класс совместим для присвоения с развёрнутым объектом, если развёрнутый объект является экземпляром типа Java-параметра. То есть, следующий оператор должен возвращать true:
развёрнутыйОбъект instanceof параметраТип
Объекты JavaClass
Если Вы передаёте объект JavaClass из JavaScript в качестве параметра Java-методу, Java конвертирует значение в соответствии с правилами, описанными в следующей таблице:
java.lang.Class
Объект разворачивается.
java.lang.JSObject
java.lang.Object
Объект JavaClas разворачивается в новый экземпляр объекта java.lang.JSObject.
java.lang.String
Объект разворачивается, вызывается метод toString развёрнутого Java-объекта и результат возвращается как новый экземпляр объекта java.lang.String.
boolean
В JavaScript 1.3 и позднее, объект разворачивается, и возникает одна из следующих ситуаций:
Если объект - null, он конвертируется в false.
Если объект имеет какое-либо другое значение, он конвертируется в true.
В JavaScript 1.2 и ранее, объект разворачивается, и возникает одна из следующих ситуаций:
Если развёрнутый объект имеет метод booleanValue, исходный объект конвертируется в return-значение.
Если развёрнутый объект не имеет метода booleanValue, конвертация терпит неудачу.
Объявление Переменных
Можно объявить переменную двумя способами:
Просто присвоив ей значение. Например, x = 42
С помощью ключевого слова var. Например, var x = 42
Область Видимости/Scope Переменной
Если Вы устанавливаете идентификатор переменной путём присваивания значения вне функции, такая переменная называется глобальной, поскольку доступна в любом месте текущего документа. Если Вы объявляете переменную внутри функции, она называется локальной, поскольку "видна"/доступна только внутри этой функции.
Использование var для объявления глобальной переменной находится на Вашем усмотрении. Однако Вы обязаны использовать var для объявления переменной внутри функции.
Вы можете обращаться к переменным, объявленным в одном окне или фрэйме, из другого окна или фрэйма, специфицируя имя окна или фрэйма. Например, если переменная phoneNumber объявлена во FRAMESET-документе, Вы можете обратиться к ней из дочернего фрэйма: parent.phoneNumber.
Обработка Исключений Java в JavaScript
Если код Java прерывается на этапе прогона программы, он вызывает исключение. Если Ваш JavaScript-код имеет доступ к члену данных Java или методу и терпит неудачу, исключение Java передаётся в JavaScript для обработки. Начиная с JavaScript 1.4, Вы можете отловить это исключение в операторе try...catch.
Например, предположим, Вы используете Java-метод forName для присвоения имени Java-класа переменной theClass. Метод forName вызывает исключение, если передаваемое Вами значение не вычисляется в имя Java-класса. Поместите оператор присвоения forName в блок try для обработки исключения:
function getClass(javaClassName) {
try {
var theClass = java.lang.Class.forName(javaClassName);
} catch (e) {
return ("The Java exception is " + e);
}
return theClass
}
В этом примере, если javaClassName вычисляется в верное имя класса, такое как "java.lang.String", присвоение проходит успешно. Если javaClassName вычисляется в неверное имя класса, такое как "String", функция getClass отлавливает исключение и возвращает нечто подобное:
The Java exception is java.lang.ClassNotFoundException: String
См. в разделе информацию об исключениях JavaScript.
Обработка Ошибок JavaScript в Java
Когда JavaScript-код вызываемый из Java, терпит неудачу на этапе прогона программы, он вызывает исключение. Если Вы вызываете JavaScript-код из Java, Вы можете отловить это исключение в операторе try...catch. Исключение JavaScript доступно в Вашем Java-коде как экземпляр netscape.javascript.JSException.
JSException это Java-оболочка вокруг исключения любого типа, вызываемого в JavaScript, аналогично тому, как экземпляры JSObject являются оболочками для JavaScript-объектов. Используйте JSException, если Вы вычисляете JavaScript-код в Java.
Если Вы вычисляете JavaScript-код в Java, следующие ситуации могут вызвать ошибки времени выполнения:
Код JavaScript не вычисляется или из-за ошибки компиляции JavaScript, или из-за какой-нибудь другой ошибки времени выполнения.
Интерпретатор JavaScript генерирует сообщение об ошибке, которое конвертируется в экземпляр JSException.
Java успешно вычисляет JavaScript-код, но JavaScript-код выполняет необработанный оператор throw.
JavaScript вызывает исключение, которое обёрнуто как экземпляр JSException. Используйте метод getWrappedException из JSException для развёртывания этого исключения в Java.
Например, предположим, что Java-объект eTest вычисляет строку jsCode, которую Вы ему передали. Вы можете отреагировать на любую ошибку времени выполнения, возникающую при вычислении, реализуя такой обработчик исключения:
import netscape.javascript.JSObject;
import netscape.javascript.JSException;
public class eTest {
public static Object doit(JSObject obj, String jsCode) {
try {
obj.eval(jsCode);
} catch (JSException e) {
if (e.getWrappedException()==null)
return e;
return e.getWrappedException();
}
return null;
}
}
В этом примере код блока try пытается вычислить строку jsCode, переданную ему Вами. Скажем, Вы передали строку "myFunction()" в качестве значения jsCode. Если myFunction не определена как функция JavaScript, интерпретатор JavaScript не может вычислить jsCode. Интерпретатор генерирует сообщение об ошибке, Java-обработчик отлавливает сообщение, а метод doit возвращает экземпляр объекта netscape.javascript.JSException.
Предположим, однако, что myFunction определена в JavaScript так:
function myFunction() {
try {
if (theCondition == true) {
return "Everything's ok";
} else {
throw "JavaScript error occurred" ;
}
} catch (e) {
if (canHandle == true) {
handleIt();
} else {
throw e;
}
}
}
Если theCondition - false, функция вызывает исключение. Это исключение отлавливается в коде JavaScript, и, если canHandle - true, JavaScript обрабатывает исключение. Если canHandle - false, исключение повторно вызывается, Java-обработчик отлавливает его, а метод doit возвращает Java-строку:
JavaScript error occurred
См. в разделе полную информацию об исключениях JavaScript.
Обратная Совместимость
В JavaScript 1.3 и ранее, класс JSException имел три public-конструктора, которые по выбору принимали строковой аргумент, специфицирующий детали сообщения или другую информацию для исключения. Метод getWrappedException отсутствовал.
Используйте оператор try...catch для обработки LiveConnect-исключений в JavaScript 1.3 и более ранних версиях таким образом:
try {
global.eval("foo.bar = 999;");
} catch (Exception e) {
if (e instanceof JSException) {
jsCodeFailed()";
} else {
otherCodeFailed();
}
}
В этом примере оператор eval терпит неудачу, если foo не определено. Блок catch выполняет метод jsCodeFailed, если оператор eval в блоке try вызывает JSException; метод otherCodeFailed выполняется в случае, если блок try вызывает какую-либо иную ошибку.
Операции
В этом разделе рассмотрены операции и содержится информация о приоритете выполнения операций.
В JavaScript имеются следующие типы операций:
В JavaScript имеются бинарные и унарные операции. Для выполнения бинарной операции необходимы два операнда: один до знака операции и один - после:
операнд1 операция операнд2
Например, 3+4 или x*y.
Для выполнения унарной операции необходим один операнд, до или после знака операции:
операция операнд
или
операнд операция
Например, x++ или ++x.
Кроме того, в JavaScript есть условная тернарная операция. Она требует наличия трёх операндов.
Операции Присвоения
Операция присвоения присваивает левому операнду значение на базе правого операнда. Базовой операцией присвоения является знак равенства (=), который присваивает левому операнду значение правого операнда. То есть, x = y присваивает значение y переменной x.
Другие операции присвоения являются сокращёнными формами записи стандартных операций, как показано в таблице.
x += y | x = x + y |
x -= y | x = x - y |
x *= y | x = x * y |
x /= y | x = x / y |
x %= y |
x = x % y |
x <<= y | x = x << y |
x >>= y | x = x >> y |
x >>>= y |
x = x >>> y |
x &= y | x = x & y |
x ^= y | x = x ^ y |
x |= y | x = x | y |
Операции Сравнения
Операция сравнения сравнивает операнды и возвращает логическое значение на базе верности сравнения. Операндами могут быть числа, строки, логические значения и объекты. Строки сравниваются на базе стандартного лексикографического порядка с использованием значений Unicode. В таблице даны операции сравнения.
Равно (==)
Возвращает true, если операнды равны. Если операнды разных типов, JavaScript пытается конвертировать операнды до типа, пригодного для сравнения.
3 == var1
"3" == var1
3 == '3'
Не равно (!=)
Возвращает true, если операнды не равны. Если операнды разных типов, JavaScript пытается конвертировать операнды до типа, пригодного для сравнения.
var1 != 4
var2 != "3"
Строго равно (===)
Строго не равно (!==)
Возвращает true, если операнды не равны и/или не одного типа.
var1 !== "3"
3 !== '3'
Больше (>)
Больше или равно (>=)
Возвращает true, если левый операнд больше правого или равен ему.
var2 >= var1
var1 >= 3
Меньше (<)
Возвращает true, если левый операнд меньше правого.
Возвращает true, если левый операнд меньше правого или равен ему.
var1 <= var2
var2 <= 5
Эти примеры предполагают, что переменной var1 присвоено значение 3, а переменной var2 значение 4.
Операция "запятая"
Операция "запятая" (,) просто вычисляет оба операнда и возвращает значение второго операнда. Первоначально использовалась внутри цикла for, чтобы дать возможность обновлять значения нескольких переменных за один проход цикла.
Например, если имеется 2-мерный массив из 10 элементов по измерению, следующий код использует операцию "запятая" для инкремента двух переменных за один проход. Печатаются значения элементов по диагонали массива:
for (var i=0, j=9; i <= 9; i++, j--)
document.writeln("a["+i+","+j+"]= " + a[i*10 +j])
Заметьте, что двухмерные массивы ещё не поддерживаются. Этот пример эмулирует двухмерный массив, используя одномерный массив.
Оператор break
Используйте оператор break для прерывания цикла switch или оператора с меткой label.
Если Вы используете break без label, он немедленно прерывает ближайший содержащий while, do-while, for или switch и передаёт управление следующему оператору.
Если Вы используете break с label, он прерывает специфицированный помеченный оператор.
Синтаксис оператора break таков:
1. break
2. break label
Первый вариант прерывает ближайший содержащий цикл или switch; второй вариант прерывает специфицированный оператор, имеющий метку.
Пример.
Здесь выполняется итерация по элементам массива, пока не будет найден индекс элемента со значением theValue:
for (i = 0; i < a.length; i++) {
if (a[i] = theValue)
break;
}
Оператор continue
Оператор continue используется для рестарта операторов while, do-while, for и label.
Если Вы используете continue без label, он прерывает текущую итерацию ближайшего цикла while, do-while или for и продолжает выполнение этого цикла со следующей итерации. В отличие от оператора break, continue не прерывает выполнение цикла полностью. В цикле while он переходит на condition. В цикле for на increment-expression.
Если Вы используете continue с label, он применяется к оператору цикла, идентифицированному этим label.
Синтаксис оператора continue таков:
1. continue
2. continue label
Пример 1.
Это пример цикла while с оператором continue, который выполняется, если значение i равно 3. Таким образом, n получает значения 1, 3, 7 и 12.
i = 0;
n = 0;
while (i < 5) {
i++;
if (i == 3)
continue;
n += i;
}
Пример 2.
Оператор, помеченный как checkiandj, содержит оператор, помеченный как checkj. Если обнаружен continue, программа прерывает текущую итерацию checkj и начинает следующую итерацию. Каждый раз при обнаружении continue, checkj начинает итерацию вновь, пока его условие не возвратит false. Если возвращено false, выполняется оставшаяся часть оператора checkiandj и checkiandj реитерирует, пока его условие не возвратит false. Если возвращается false, программа продолжает выполняться с оператора, следующего после checkiandj.
Если continue имеет label для checkiandj, программа продолжит выполнение от начала оператора checkiandj.
checkiandj :
while (i<4) {
document.write(i + "<BR>");
i+=1;
checkj :
while (j>4) {
document.write(j + "<BR>");
j-=1;
if ((j%2)==0)
continue checkj;
document.write(j + " is odd.<BR>");
}
document.write("i = " + i + "<br>");
document.write("j = " + j + "<br>");
Оператор do...while
Оператор do...while повторяется, пока специфицированное выражение - false. Оператор do...while выглядит так:
do {
statement
} while (condition)
statement выполняется один раз перед проверкой условия/condition. Если condition - true, оператор выполняется снова. В конце каждого выполнения condition проверяется. Если condition - false, выполнение останавливается и управление передаётся оператору после do...while.
Пример.
В этом примере цикл do итерируется минимум один раз и повторяет итерации, пока i меньше 5.
do {
i+=1;
document.write(i);
} while (i<5);
Оператор for
Цикл for повторяется до тех пор, пока специфицированное значение false. Цикл JavaScript for похож на циклы for Java и C. Оператор for выглядит так:
for ([initialExpression]; [condition]; [incrementExpression]) {
statements
}
Когда цикл for выполняется, происходит следующее:
Инициализирующее выражение initialЕxpression, если имеется, выполняется. Это выражение обычно инициализирует один или более счётчиков цикла, и синтаксис разрешает выражения любой сложности. Это выражение также может объявлять переменные.
Вычисляется выражение condition/условное. Если значение condition - true, выполняются statements/операторы цикла. Если значение condition - false, цикл for прекращает работу. Если выражение condition полностью отсутствует, принимается, что condition - true.
Выполняются statements.
Обновляющее выражение incrementExpression, если имеется, выполняется, и управление возвращается к .
Пример.
Эта функция содержит оператор for, который подсчитывает количество выбранных опций в прокручиваемом списке (объект Select, позволяющий выбрать несколько позиций). Оператор for объявляет переменную i и инициализирует её в нуль. Он проверяет, меньше ли i количества опций объекта Select, выполняет оператор if и инкремент переменной i на единицу после каждого прохода цикла.
<SCRIPT>
function howMany(selectObject) {
var numberSelected=0;
for (var i=0; i < selectObject.options.length; i++) {
if (selectObject.options[i].selected==true)
numberSelected++;
}
return numberSelected;
}
</SCRIPT>
<FORM NAME="selectForm">
<P><B>Choose some music types, then click the button below:</B>
<BR><SELECT NAME="musicTypes" MULTIPLE>
<OPTION SELECTED> R&B
<OPTION> Jazz
<OPTION> Blues
<OPTION> New Age
<OPTION> Classical
<OPTION> Opera
</SELECT>
<P><INPUT TYPE="button" VALUE="How many are selected?"
onClick="alert ('Number of options selected: ' + howMany(document.selectForm.musicTypes))">
</FORM>
Оператор for...in
Оператор for...in итерирует специфицированную переменную по всем свойствам объекта. Для каждого достигнутого свойства JavaScript выполняет специфицированные операторы. Оператор for...in выглядит так:
for (variable in object) {
statements }
Пример.
Эта функция принимает в качестве аргумента объект и имя объекта. Затем она итерирует по всем свойствам этого объекта и возвращает строку - список имён свойств и их значений.
function dump_props(obj, obj_name) {
var result = "";
for (var i in obj) {
result += obj_name + "." + i + " = " + obj[i] + "<BR>"
}
result += "<HR>";
return result;
}
Для объекта car со свойствами make и model результат будет таким:
car.make = Ford
car.model = Mustang
Оператор if...else
Этот оператор используется для выполнения определённых операторов, если логическое условие true; используйте необязательный блок else для выполнения других операторов, если условие false. Оператор if выглядит так:
if (condition) {
statements1
}
[else {
statements2
} ]
Условие может быть любым выражением JavaScript, вычисляемым в true или false. Выполняемые операторы могут быть любыми операторами JavaScript, включая вложенные операторы if. Если Вам нужно выполнить более одного оператора после операторов if или else, Вы обязаны заключить эти выполняемые операторы в фигурные скобки {}.
Вы не должны использовать простые присвоения в условном операторе. Например, НЕ используйте такой код:
if(x = y)
{
/* здесь всё верно */
}
Если Вам нужно использовать присвоение в условном операторе, введите дополнительные скобки вокруг операции присвоения. Например, if( (x = y) ).
Не путайте примитивные Boolean-значения true и false со значениями true и false объекта Boolean. Любой объект, чьё значение не undefined, null, zero, NaN или пустая строка, включая объект Boolean со значением false, вычисляется в true, когда передаётся условному оператору. Например:
var b = new Boolean(false);
if (b) // это условие вычисляется в true
Пример.
В этом примере функция checkData возвращает true, если количество символов в Text-объекте равно трём; иначе, выводит предупреждение и возвращает false.
function checkData () {
if (document.form1.threeChar.value.length == 3) {
return true
} else {
alert("Enter exactly three characters. " +
document.form1.threeChar.value + " is not valid.")
return false
}
}
Оператор label
Оператор label является идентификатором, на который можно ссылаться из любого места программы. Например, Вы можете использовать label для идентификации цикла, а затем использовать операторы break или continue для прерывания цикла или продолжения выполнения.
Синтаксис оператора label выглядит так:
label :
statement
Значением label может быть любой верный идентификатор JavaScript, не являющийся зарезервированным словом. Оператор/statement, идентифицируемый при помощи label, может быть любым оператором.
Пример.
В этом примере label markLoop идентифицирует цикл while.
markLoop:
while (theMark == true)
doSomething();
}
Оператор switch
Оператор switch позволяет программе вычислять выражение и пытается сопоставить значение выражения значению в метке case. Если совпадение найдено, программа выполняет ассоциированный оператор. Оператор switch выглядит так:
switch (expression){
case label :
statement;
break;
case label :
statement;
break;
...
default : statement;
}
Программа сначала ищет label, совпадающий со значением expression, а затем выполняет ассоциированный statement/оператор. Если совпадающий label не найден, программа ищет необязательный default statement/оператор по умолчанию и, если он найден, выполняет ассоциированный оператор. Если default statement не найден, программа продолжает выполнять оператор, следующий после конца оператора switch.
Необязательный оператор break, ассоциированный с меткой case label, гарантирует, что программа прервёт выполнение оператора switch, как только будет выполнен оператор найденного совпадения, и продолжит выполнение с оператора, идущего после оператора switch. Если break отсутствует, программа продолжает выполнение следующего оператора внутри оператора switch.
Пример.
Здесь, если expr вычисляется в "Bananas", программа находит совпадение с case "Bananas" и выполняет ассоциированный оператор. Если обнаружен break, программа прерывает switch и выполняет оператор после блока оператора switch. Если break отсутствует, оператор в case "Cherries" также будет выполнен.
switch (expr) {
case "Oranges" :
document.write("Oranges are $0.59 a pound.<BR>");
break;
case "Apples" :
document.write("Apples are $0.32 a pound.<BR>");
break;
case "Bananas" :
document.write("Bananas are $0.48 a pound.<BR>");
break;
case "Cherries" :
document.write("Cherries are $3.00 a pound.<BR>");
break;
default :
document.write("Sorry, we are out of " + i + ".<BR>");
}
document.write("Is there anything else you'd like?<BR>");
Оператор throw
Оператор throw используется для вызова исключения. Если Вы вызываете исключение, Вы специфицируете выражение, содержащее значение исключения:
throw expression
Следующий код вызывает несколько исключений.
throw "Error2"; // генерирует исключение со строковым значением
throw 42; // генерирует исключение со значением 42
throw true; // генерирует исключение со значением true
При вызове исключения Вы можете специфицировать объект. Затем можно обратиться к свойствам объекта в блоке catch. Следующий пример создаёт объект myUserException типа UserException и использует его в операторе throw.
// Создаётся объект типа UserException
function UserException (message) {
this.message=message;
this.name="UserException";
}
// Создаётся и вызывается экземпляр объекта
myUserException=new UserException("Value too high");
throw myUserException;
Оператор try...catch
Оператор try...catch помечает блок операторов, пытается их выполнить и специфицирует один или более вариантов ответа при возникновении исключения. Если исключение возникло, оператор try...catch отлавливает его.
Оператор try...catch состоит из блока try, который содержит один или более операторов, и нуль или более блоков catch, содержащих операторы, которые специфицируют действия при вызове исключения в блоке try. То есть, если Вы хотите выполнить блок try и он не выполняется, Вы передаёте управление в блок catch. Если любой оператор блока try (или оператор функции, вызываемой из блока try) вызывает исключение, управление немедленно передаётся в блок catch. Если исключение не было вызвано, блок catch пропускается. Блок finally выполняется после выполнения блоков try и catch, но до выполнения оператора, идущего после блока оператора try...catch.
В следующем примере используется оператор try...catch. Вызывается функция, которая запрашивает название месяца из массива, базируясь на значении, передаваемом функции. Если значение не соответствует номеру месяца (1-12), вызывается исключение со значением "InvalidMonthNo" и операторы блока catch устанавливают переменную в monthName значение "unknown".
function getMonthName (mo) {
mo=mo-1; // Уточняется номер месяца по индексу массива (1=Jan, 12=Dec)
var months=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul",
"Aug","Sep","Oct","Nov","Dec");
if (months[mo] != null) {
return months[mo]
} else {
throw "InvalidMonthNo"
}
}
try {
// попытка выполнить эти операторы:
monthName=getMonthName(myMonth) // функция может вызвать исключение
}
catch (e) {
monthName="unknown"
logMyErrors(e) // объект, вызвавший исключение, передаётся обработчику исключений
}
Блок catch
Вы можете использовать единственный блок catch для обработки всех исключений, которые могут быть сгенерированы в блоке try, или можете использовать отдельные блоки catch для обработки определённых типов исключений.
Единственный блок catch
Используйте единственный в данном операторе try...catch блок catch (восстанавливающий блок) для выполнения кода обработки ошибок для каждого исключения, вызываемого в блоке try.
Единственный блок catch имеет следующий синтаксис:
catch (catchID) {
statements
}
Блок catch специфицирует идентификатор (catchID в предыдущем синтаксисе), по которому содержится значение, специфицированное оператором throw; Вы можете использовать этот идентификатор для получения информации о вызванном исключении. JavaScript создаёт этот идентификатор при входе в блок catch; идентификатор существует только в период выполнения блока catch; после завершения выполнения блока catch идентификатор больше не доступен.
Например, следующий код вызывает исключение. Если возникает исключение, управление передаётся в блок catch.
try {
throw "myException" // генерируется исключение
}
catch (e) {
// операторы для обработки любого исключения
logMyErrors(e) // исключение передаётся обработчику ошибок
}
Несколько блоков catch
Единственный оператор try может содержать несколько условных блоков catch, каждый из которых обрабатывает специфический тип исключения. В этом случае вход в подходящий условный блок catch выполняется только при вызове исключения, специфицированного для данного блока. Вы можете также по выбору включить отдельный блок catch для всех неспецифицированных исключений как финальный блок catch в операторе.
Например, следующая функция вызывает три другие функции (объявленные в другом месте), которые проверяют её аргументы. Если проверяющая функция определяет, что проверяемый компонент неверен, она возвращает 0, заставляя вызывающую функцию вызывать определённое исключение.
function getCustInfo(name, id, email)
{
var n, i, e;
if (!validate_name(name))
throw "InvalidNameException"
else
n = name;
if (!validate_id(id))
throw "InvalidIdException"
else
i = id;
if (!validate_email(email))
throw "InvalidEmailException"
else
e = email;
cust = (n + " " + i + " " + e);
return (cust);
}
Условные блоки catch управляют вызовом соответствующего обработчика исключений.
try {
// функция может вызвать три вида исключений
getCustInfo("Lee", 1234, "lee@netscape.com")
}
catch (e if e == "InvalidNameException") {
// вызывает обработчик неправильных имён
bad_name_handler(e)
}
catch (e if e == "InvalidIdException") {
// вызывает обработчик неправильных ids/идентификаторов
bad_id_handler(e)
}
catch (e if e == "InvalidEmailException") {
// вызывает обработчик неправильных email-адресов
bad_email_handler(e)
}
catch (e){
// незвестное исключение записывается в log-файл
logError(e)
}
Блок finally
Блок finally содержит операторы, выполняемые после выполнения блоков try и catch, но до выполнения операторов, идущих после оператора try...catch. Блок finally выполняется независимо от того, было ли вызвано исключение. Если исключение вызывается, операторы блока finally выполняются даже в том случае, если ни один блок catch не обработал исключение.
Вы можете использовать блок finally для корректного завершения скрипта при возникновении исключения; например, Вам может понадобиться освободить ресурс, связанный скриптом. В следующем примере файл открывается и операторы работают с ним (серверный JavaScript даёт возможность доступа к файлам). Если вызывается исключение при открытом файле, блок finally закрывает файл до того, как скрипт потерпит неудачу.
openMyFile();
try {
writeMyFile(theData)
}
finally {
closeMyFile() // ресурс всегда закрывается
}
Вложение операторов try...catch
Вы можете вкладывать один или более операторов try...catch друг в друга. Если внутренний оператор try...catch не имеет блока catch, на совпадение проверяется блок catch содержащего его оператора try...catch.
Copyright © 2000 Все Права Зарезервированы.
Дата последнего обновления 28 сентября 2000 года.