Клиентский JavaScript 1.3 Руководство

Что такое JavaScript?

JavaScript это разработанный корпорацией Netscape межплатформенный объектно-ориентированный язык скриптинга (сценариев). Ядро JavaScript содержит набор основных объектов, таких как Array, Date и Math, и основной набор элементов языка, таких как операции, управляющие структуры и операторы. Ядро JavaScript может быть расширено путём предоставления дополнительных объектов; например:
  • Клиентский JavaScript расширяет ядро языка за счёт объектов, управляющих браузером (Navigator или другой подобный web-браузер) и его Document Object Model (DOM). Например, клиентские расширения позволяют приложению размещать элементы на HTML-форме и отвечать на пользовательские события, такие как щелчок мышью, ввод данных в форму и навигация по страницам.

  • Серверный JavaScript расширяет ядро языка за счёт объектов, имеющих отношение к работе JavaScript на сервере. Например, серверные расширения позволяют подключиться к реляционной БД, поддерживать непрерывность информации между вызовами приложения или работать с файлами на сервере.

  • JavaScript даёт Вам возможность создавать приложения, работающие в Internet. Клиентские приложения работают в браузере, таком как Netscape Navigator, а серверные приложения запускаются на сервере, таком как Netscape Enterprise Server. Используя JavaScript, Вы можете создавать динамические HTML-страницы, которые обрабатывают пользовательский ввод и работают с данными через использование специальных объектов, файлов и реляционных баз данных.
    С помощью функциональности LiveConnect Вы можете дать возможность коду Java и JavaScript взаимодействовать. Из JavaScript Вы можете инстанциировать Java-объекты и получить доступ к их public-методам и полям. Из Java Вы можете иметь доступ к объекта, методам и свойствам JavaScript.
    Netscape изобрела JavaScript, и JavaScript впервые был использован в браузерах Netscape.

    Документация JavaScript и спецификация ECMA

    Документация JavaScript и спецификация ECMA

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

    Ядро JavaScript

    Ядро JavaScript

    Клиентский и серверный JavaScript имеют следующие общие элементы:

  • Ключевые слова

  • Синтаксис и грамматику операторов

  • Требования к выражениям, переменным и литералам

  • Объектную модель (хотя клиентский и серверный JavaScript имеют разные наборы предопределённых объектов)

  • Предопределённые объекты и функции, такие как Array, Date и Math


  • JavaScript и Java

    JavaScript и Java похожи, но имеют фундаментальные отличия. Язык JavaScript напоминает Java, но не имеет статической типизации и строгой проверки типов Java. JavaScript в основном поддерживает синтаксис выражений Java и базовые конструкции управления потоком.
    В отличие от системы времени компиляции классов Java, построенной на объявлениях, JavaScript поддерживает систему времени прогона, базирующуюся на небольшом количестве типов данных: числовых, Булевых и строковых значениях. JavaScript имеет объектную модель на основе прототипов, а не более распространённую модель на основе классов. Модель на прототипах предоставляет возможность динамического наследования; то есть то, что наследуется, может варьироваться для разных объектов. JavaScript также поддерживает функции без специальных требований к объявлению. Функции могут быть свойствами объектов, выполняясь как слабо типизированные методы.
    JavaScript намного более свободен по форме по сравнению с Java. Вы не должны объявлять все переменные, классы и методы. Вы не должны учитывать, какие методы являются public, private или protected и Вы не должны реализовывать интерфейсы. Возвращаемые значения переменных, параметров и функций не являются явно типизированными.
    Java это язык программирования на основе классов, созданный для быстрого выполнения и строгой проверки типов. Строгая проверка типов означает, к примеру, что Вы не можете привести/cast целое число Java к ссылке на объект или получить доступ к private-памяти, нарушив байт-коды Java. Модель классов Java означает, что программы состоят исключительно из классов и их методов. Наследование классов Java и строгая типизация обычно требуют плотно выстроенной иерархии объектов. Эти требования делают программирование на Java более сложным, чем авторизация в JavaScript.
    JavaScript по духу происходит от небольших, динамически типизируемых языков, таких как HyperTalk и dBASE. Эти языки программирования являются утилитами программирования для широкой аудитории, так как имеют упрощённый синтаксис, специализированную встроенную функциональность и минимальные требования при создании объектов.

    JavaScript и спецификация ECMA

    Корпорация Netscape изобрела JavaScript, и JavaScript впервые был использован в Netscape-браузерах. Одновременно Netscape работает совместно с ECMA (European Computer Manufacturers Association) над созданием стандартизованного международного языка программирования на основе ядра JavaScript. ECMA это международная ассоциация стандартов для информационных и коммуникационных систем. эта стандартизованная версия JavaScript, называемая ECMAScript, работает совершенно одинаково во всех приложениях, поддерживающих данный стандарт. Компании могут использовать этот открытый стандартный язык для разработки своих реализаций JavaScript. Первая версия стандарта ECMA документирована в спецификации ECMA-262.
    Стандарт ECMA-262 одобрен также ISO (International Organization for Standards) как ISO-16262. Вы можете найти PDF-версию ECMA-262 на сайте Netscape DevEdge Online. Вы можете также найти
    эту спецификацию на web-сайте ECMA
    . Спецификация ECMA не описывает Document Object Model (DOM), которая стандартизована консорциумом World Wide Web Consortium (W3C). DOM определяет способ, которым HTML-объекты документа экспонируются Вашему скрипту.

    Клиентский JavaScript

    Клиентский JavaScript

    Web-браузеры, такие как Navigator (2.0 и более поздние версии), могут интерпретировать операторы клиентского JavaScript, внедрённые в HTML-страницу. Если браузер (или клиент) запрашивает такую страницу, сервер высылает полное содержимое документа, включая HTML и операторы JavaScript, клиенту по сети. Браузер читает страницу сверху вниз, отображая результирующий HTML и выполняя операторы JavaScript по мере из обнаружения. Этот процесс, показанный на следующем рисунке, выдает пользователю конечный результат.

    Отладка в JavaScript

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

  • Netscape JavaScript Debugger 1.1 - введение в Debugger.

  • Вы можете загрузить Debugger с указанного URL. Загружаемый файл это SmartUpdate .jar. Для установки Debugger загрузите этот .jar-файл в Navigator: используйте процедуру, описанную в вышеуказанном URL, или введите URL к .jar-файлу в поле location (адресную строку).
  • Getting Started with Netscape JavaScript Debugger объясняет, как пользоваться Отладчиком.


  • Язык JavaScript

    Рисунок 1.1 Язык JavaScript

    Язык JavaScript
    Следующие разделы являются введением в JavaScript на клиенте и на сервере.

    Клиентский JavaScript

    Рисунок 1.2 Клиентский JavaScript

    Клиентский JavaScript
    Операторы клиентского JavaScript, внедрённые в HTML-страницу, могут реагировать на пользовательские события, такие как щелчок мыши, ввод данных в форму и навигация по странице. Например, Вы можете написать функцию JavaScript для проверки правильности введённой пользователем в форму информации - номера телефона или zip-кода. Без передачи по сети, JavaScript, внедрённый на HTML-страницу, может проверить введённые данные и вывести диалоговое окно, если пользователь ввёл неправильные данные.
    Разные версии JavaScript работают с конкретными версиями Navigator'а. Например, JavaScript 1.2 предназначен для Navigator 4.0. Некоторые возможности JavaScript 1.2 недоступны в JavaScript 1.1 и, следовательно, недоступны в Navigator 3.0. О версиях JavaScript и Navigator см. "Версии JavaScript".

    Серверный JavaScript в процессе разработки

    Рисунок 1.3 Серверный JavaScript в процессе разработки

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

    Серверный JavaScript на этапе прогона

    Рисунок 1.4 Серверный JavaScript на этапе прогона

    Серверный JavaScript на этапе прогона
    В отличие от стандартных программ Common Gateway Interface (CGI), весь исходный JavaScript интегрируется непосредственно в HTML-страницы, ускоряя разработку и облегчая обслуживание. Служба Session Management Service серверного JavaScript содержит объекты, которые Вы можете использовать для обслуживания данных, существующих в промежутке между клиентскими запросами, нескольких клиентов и нескольких приложений. Служба LiveWire Database Service серверного JavaScript предоставляет объекты для доступа к БД, являясь интерфейсом для Structured Query Language (SQL)-серверов БД.

    Серверный JavaScript

    Серверный JavaScript

    Серверный JavaScript также встраивается в HTML-страницы. Серверные операторы могут подключать к реляционным БД разных производителей, предоставлять информацию в совместное использование несколькими потребителями, давать доступ к файловой системе сервера или взаимодействовать с другими приложениями через LiveConnect и Java. HTML-страницы с серверным JavaScript могут также содержать клиентский JavaScript.
    В отличие от страниц, написанных на чисто клиентском JavaScript, HTML-страницы с серверным JavaScript компилируются в байт-код исполняемых файлов. Эти исполняемые файлы запускаются web-сервером, имеющим машину выполнения JavaScript. Поэтому создание приложений JavaScript это процесс из двух этапов.
    На первом этапе, показанном на Рисунке 1.3, Вы создаёте HTML-страницы (которые могут содержать операторы клиентского и серверного JavaScript) и JavaScript-файлы. Затем Вы компилируете все эти файлы в единый исполняемый файл.

    Соотношение версий JavaScript и ECMA

    Соотношение версий JavaScript и ECMA

    Netscape тесно сотрудничает с ECMA для создания ECMA-спецификации. В таблице показано соотношение между версиями JavaScript и ECMA.

    JavaScript в сравнении с Java

    Таблица 1.1 JavaScript в сравнении с Java


    JavaScript
    Java
    Интерпретируется (не компилируется) клиентом.Скомпилированные байт-коды загружаются с сервера, выполняются на клиенте.
    Объектно-ориентированный. Нет отличий в типах объектов. Наследование идёт через механизм прототипов, а свойства и методы могут динамически добавляться к любому объекту.На основе классов. Объекты делятся на классы и экземпляры с наследованием по всей цепи иерархии классов. Классы и экземпляры не могут иметь свойства или методы, добавляемые динамически.
    Код, интегрированный с и внедрённый в HTML.Аплеты отличаются от HTML (при доступе из HTML-страниц).
    Тип данных переменной не объявляется (динамическая типизация).Тип данных переменной обязан быть объявлен (статическая типизация).
    Не может автоматически записывать на жёсткий диск.Не может автоматически записывать на жёсткий диск.

    Об отличиях JavaScript и Java см. также Главу 8 "Объектная Модель. Детали".

    Версии JavaScript и ECMA

    Таблица 1.2 Версии JavaScript и ECMA

    Версия JavaScript
    Сравнение с версией ECMA
    JavaScript 1.1ECMA-262 основан на JavaScript 1.1.
    JavaScript 1.2Работа над ECMA-262 не была завершена в момент выхода JavaScript 1.2.

    JavaScript 1.2 не полностью совместим с ECMA-262 по следующим причинам:

  • Netscape разработал дополнения для JavaScript 1.2, которые не были учтены в ECMA-262.

  • ECMA-262 добавил интернационализацию с использованием Unicode и универсальное поведение на всех платформах. Серверные возможности JavaScript 1.2, такие как объект Date, были платформозависимыми и использовали поведение, специфическое для конкретных платформ.
  • JavaScript 1.3JavaScript 1.3 полностью совместим с ECMA-262.
    В JavaScript 1.3 устранено несоответствие JavaScript 1.2 с ECMA-262 при сохранении всех дополнительных возможностей JavaScript 1.2, исключая == и !=, которые были изменены для обеспечения соответствия ECMA-262. Эти дополнительные возможности, включая некоторые новые из JavaScript 1.3, не являющиеся частью ECMA, рассматриваются при создании второй версии спецификации ECMA.
    Например, JavaScript 1.2 и 1.3 поддерживают регулярные выражения, которые не вошли в ECMA-262. Вторая версия спецификации ECMA не была закончена, когда JavaScript 1.3 был опубликован.

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

    Visual JavaScript

    Netscape Visual JavaScript это утилита визуальной разработки на базе компонентов для платформы Netscape Open Network Environment (ONE). Она предназначена в основном для использования разработчиками, которые хотят создавать платформонезависимые web-приложения на основе стандартов из готовых к использованию компонентов с минимальными затратами на программирование. Эти приложения основаны на HTML, JavaScript и Java.
    О Visual JavaScript см. книгу Visual JavaScript Developer's Guide.

    Клиентский JavaScript 1.3 Руководство

    Булевы литералы

    Булевы литералы

    Тип Boolean имеет два литеральных значения: true и false.
    Не путайте Булевы значения true и false со значениями true и false объекта Boolean. Объект Boolean является оболочкой для примитивного типа данных Boolean. См. "Объект Boolean".

    Целые числа

    Целые числа

    Целые числа могут быть десятеричными (база 10), 16-ричными (база 16) и 8-ричными (база 8). Десятеричный целочисленный литерал состоит из последовательности цифр без ведущего нуля (0). Ведущий 0 (нуль) в целочисленном литерале означает, что это восьмеричное число; ведущие символы 0x (или 0X) указывают, то это 16-ричное число.

    16-ричные цифры могут состоять из цифр (0-9) и английских букв a-f и A-F. Восьмеричные целые могут состоять только из цифр 0-7.
    Вот примеры целочисленных литералов: 42, 0xFFF, -345.

    Escape-последовательности Unicode

    Escape-последовательности Unicode

    Вы можете использовать escape-последовательности (замены) Unicode в строковых литералах. Такая escape-последовательность состоит из шести ASCII-символов: \u и четырёх 16-ричных цифр. Например, \u00A9 это символ copyright. Каждая escape-последовательность Unicode в JavaScript интерпретируется как одиночный символ.
    Следующий код возвращает символ copyright и строку "Netscape Communications".
    x="\u00A9 Netscape Communications"
    В таблице перечислены часто используемые специальные символы и их Unicode-значения.

    Использование специальных символов в строках

    Использование специальных символов в строках

    Помимо обычных символов, Вы можете также включать в строки специальные символы, как показано в следующем примере.
    "одна строка \n другая строка"
    В таблице перечислены специальные символы, которые Вы можете использовать в строках JavaScript.

    Конвертация типов данных

    Конвертация типов данных

    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

    Лишние запятые в литералах массива

    Лишние запятые в литералах массива

    Вы не должны специфицировать все элементы в литерале массива. Если Вы поместите подряд две запятые, создаётся массив с пробелами для неспецифицированных значений. В следующем примере создаётся массив fish:
    fish = ["Lion", , "Angel"]
    В это массиве имеются два элемента со значениями и один пустой элемент (fish[0] равен "Lion", fish[1] равен undefined, fish[2] равен "Angel"):
    Если Вы вставили ведомую запятую в конце списка элементов, эта запятая игнорируется. В следующем примере размер массива равен 3. Элемента myList[3] нет. Все остальные запятые в списке обозначают новый элемент.
    myList = ['home', , 'school', ];
    В следующем примере размер массива равен 4, а элемент myList[0] отсутствует.
    myList = [ , 'home', , 'school'];
    В следующем примере размер массива равен 4, а элемент myList[3] отсутствует. Игнорируется только последняя запятая. Эта ведомая запятая не обязательна.
    myList = ['home', , 'school', , ];

    Литералы массива

    Литералы массива

    Литерал массива это список из 0 или более выражений, каждое из которых представляет элемент массива, заключённый в квадратные скобки ([]). Если Вы создаёте массив с использованием литерала массива, он инициализируется специфицированными значениями в качестве элементов и получает размер, равный количеству специфицированных аргументов.
    В этом примере создаётся массив coffees из трёх элементов, имеющий размер 3:
    coffees = ["French Roast", "Columbian", "Kona"]
    ПРИМЕЧАНИЕ:
    Литерал массива это тип инициализатора объекта. См. "Использование Инициализаторов Объектов".
    Если массив создаётся путём использования литерала в скрипте верхнего уровня, JavaScript интерпретирует массив каждый раз, когда вычисляет выражение, содержащее литерал массива. Кроме того, используемый в функции литерал создаётся каждый раз при вызове функции.
    Литералы массива являются также Array-объектами. См. в разделе "Объект Array" детальную информацию об объектах Array.

    Литералы объекта

    Литералы объекта

    Литерал объекта это список из 0 или более пар из имён свойств объекта и их значений, заключённый в фигурные скобки ({}). Вы не должны использовать литерал объекта в начале оператора. Это приведёт к ошибке.
    Далее идёт пример литерала объекта. Первый элемент объекта car определяет свойство myCar; второй элемент, свойство getCar, вызывает функцию (Cars("honda")); третий элемент, свойство special, использует существующую переменную (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
    Кроме того, Вы можете использовать индексирование объекта, свойство index (например, 7), или вкладывать объекты друг в друга. В следующем примере используются эти возможности, однако они могут не поддерживаться другими браузерами, совместимыми с ECMA.
    car = {manyCars: {a: "Saab", b: "Jeep"}, 7: "Mazda"}document.write(car.manyCars.b); // Jeep
    document.write(car[7]); // Mazda

    Литералы с плавающей точкой

    Литералы с плавающей точкой

    Литерал с плавающей точкой может иметь следующие составные части:

  • десятеричное целое
  • десятичная точка (".")

  • дробная часть (другое 10-ричное число)
  • экспонента

  • Часть "экспонента" это английская буква "e" или "E" с последующим целым числом, которое может иметь знак (предшествующий "+" или "-"). Литерал с плавающей точкой обязан иметь как минимум одну цифру и десятичную точку, либо "e" (или "E").
    Вот некоторые примеры литералов с плавающей точкой: 3.1415, -3.1E12, .1e12, 2E-12

    Литералы

    Литералы используются в JavaScript для представления значений. Это фиксированные значения, не переменные, которые Вы литерально\буквально предоставляете скрипту.
    В этом разделе описаны следующие типы литералов:

  • Литералы массива

  • Булевы литералы

  • Литералы с плавающей точкой
  • Целые числа

  • Литералы объекта
  • Строковые литералы


  • Объявление переменных

    Объявление переменных

    Вы может объявить переменную двумя способами:

  • Просто присвоив ей значение. Например, x = 42

  • С помощью ключевого слова var. Например, var x = 42


  • Область видимости переменной

    Область видимости переменной

    Если Вы устанавливаете идентификатор переменной путём присвоения вне функции, такая переменная называется глобальной, поскольку доступна в любом месте документа. Если Вы объявляете переменную внутри функции, она называется
    локальной переменной, поскольку доступна только внутри данной функции.
    Использование var при объявлении глобальной переменной не требуется. Однако Вы обязаны использовать var при объявлении переменой внутри функции.
    Вы можете получить доступ к глобальным переменным, объявленным в одном окне или фрэйме, из другого окна или фрэйма, специфицируя имя окна или фрэйма. Например, если переменная phoneNumber объявляется в документе FRAMESET, Вы можете обратиться к этой переменной из дочернего фрэйма так: parent.phoneNumber.

    Переменные

    Вы используете переменные как символические имена для значений. Вы даёте переменной имя, по которому Вы ссылаетесь на неё и которое обязано соответствовать определённым требованиям.
    Идентификатор в JavaScript, или name\имя, обязан начинаться с буквы или символа подчёркивания ("_"); последующие символы также могут быть цифрами (0-9). Поскольку JavaScript чувствителен к регистру символов, могут использоваться буквы (английские) от "A" до "Z" (верхний регистр) и от "a" до "z" (нижний регистр).
    Вот некоторые примеры правильных имён: Number_hits, temp99, _name.

    Совместимость Unicode с ASCII и ISO

    Совместимость Unicode с ASCII и ISO

    Unicode совместим с символами ASCII и поддерживается многими программами. Первые 128 символов Unicode соответствуют символам ASCII и имеют те же байтовые значения. Символы Unicode с U+0020 по U+007E эквивалентны символам ASCII с 0x20 по 0x7E. В отличие от ASCII, который поддерживает латинский алфавит и использует набор 7-битных символов, Unicode использует 16-битное значение для каждого символа. Это позволяет кодировать десятки тысяч символов. Unicode версии 2.0 содержит 38 885 символов. Он также поддерживает механизм расширения, Transformation Format (UTF), называемый UTF-16, который позволяет кодировать более миллиона символов путём использования 16-битных пар. UTF включает кодирование в реальные биты.
    Unicode полностью совместим с International Standard ISO/IEC 10646-1; 1993, который является поднабором ISO 10646, и поддерживает ISO UCS-2 (Universal Character Set), который использует два восьмеричных значения (два байта или 16 битов).
    Поддержка Unicode в JavaScript и в Navigator'е означает, что Вы можете использовать в программах на JavaScript не-латинские, международные и локализованные символы, плюс специальные технические символы. Unicode является стандартным способом кодирования многоязычных текстов. Поскольку Unicode совместим с ASCII, программы могут использовать ASCII-символы. Вы можете использовать не-ASCII символы Unicode в комментариях и строковых литералах JavaScript.

    Строковые литералы

    Строковые литералы

    Строковой литерал это 0 или более символов, заключённых в двойные (") или одинарные (') кавычки. Строка должна быть ограничена кавычками одного вида; то есть, оба знака должны быть " или '. Вот примеры строковых литералов:
    "blah"
    'blah'
    "1234"
    "первая строка \n вторая строка"
    Вы можете вызвать любые методы объекта String в строковом литеральном значении - JavaScript автоматически конвертирует строковой литерал во временный String-объект, вызывает его методы, затем уничтожает временный String-объект. Вы можете также использовать свойство String.length со строковыми литералами.
    Вы должны использовать строковые литералы, если только Вам не нужно специально использовать объект String. См. также "Объект String".

    Специальные Символы JavaScript

    Таблица 2.1 Специальные Символы JavaScript


    СимволЗначение
    \bBackspace
    \fForm feed/прогон страницы
    \nNew line/новая строка
    \rCarriage return/возврат каретки
    \tTab/табуляция
    \'Апостроф или одинарная кавычка
    \"Двойная кавычка
    \\Обратный слэш (\)
    \XXXСимвол из набора Latin-1, специфицированный тремя восьмеричными цифрами XXX в диапазоне от 0 до 377. Например, \251 это восьмеричная последовательность для символа copyright.
    \xXXСимвол из набора Latin-1, специфицированный двумя 16-ричными цифрами XX в диапазоне от 00 до FF. Например, \xA9 это 16-ричная последовательность для символа copyright.
    \uXXXXСимвол Unicode, специфицированный четырьмя 16-ричными цифрами XXXX. Например, \u00A9 это Unicode-последовательность для символа copyright. См. также "Escape-последовательности Unicode".


    Unicode-значения специальных символов

    Таблица 2.2 Unicode-значения специальных символов


    КатегорияUnicode-значение
    ИмяFormat-имя
    Пробельные символы\u0009Tab/табуляция
    \u000BVertical Tab/вертикальная табуляция
    \u000CForm Feed/прогон страницы
    \u0020Space/пробел
    Терминаторы строки\u000ALine Feed/прогон строки
    \u000DCarriage Return/возврат каретки
    Дополнительные escape-последовательности Unicode\u000bBackspace
    \u0009Horizontal Tab/горизонтальная табуляция
    \u0022Double Quote/двойная кавычка"
    \u0027Single Quote/одинарная кавычка'
    \u005CBackslash/обратный слэш\

    JavaScript использует escape-последовательности Unicode иначе, чем Java. В JavaScript escape-последовательность никогда сначала не интерпретируется как специальный символ. Например, последовательность терминатора строки внутри строки не обрывает строку до того как будет интерпретирована функцией. JavaScript игнорирует любую escape-последовательность внутри комментария. В Java, если escape-последовательность используется в однострочном комментарии, она интерпретируется как символ Unicode. Для строкового литерала, компилятор Java сначала интерпретирует escape-последовательности. Например, если escape-символ обрыва строки (\u000A) используется в Java, он обрывает строковой литерал. В Java это приводит к ошибке, поскольку терминаторы строки не допускаются в строковых литералах. Вы обязаны использовать \n для line feed в строковом литерале. В JavaScript эта escape-последовательность работает так же, как \n.

    Unicode

    Unicode это универсальный стандарт кодирования символов для обмена и отображения символов основных письменных языков. Он покрывает языки Америки, Европы, Среднего Востока, Африки, Индии, Азии и Океании, а также мёртвые языки и технические символы. Unicode даёт возможность передавать, обрабатывать и отображать многоязычные тексты, а также использовать общепринятые математические и технические символы. Таким образом предполагается разрешить проблемы интернационализации в многоязычной компьютерной среде, такие как различные национальные символьные стандарты. Не все современные и архаичные виды письма, однако, поддерживаются в настоящее время.
    Набор символов Unicode можно использовать для всех известных кодировок. Unicode смоделирован после набора ASCII (American Standard Code for Information Interchange). В нём используется числовое значение и имя для каждого символа. Кодировка символов специфицирует идентификацию символа и числовое значение (кодовую позицию), а также битовое представление этого значения. 16-битное числовое значение (кодовое значение) определяется 16-ричным числом и префиксом U, например, U+0041 представляет букву A. Уникальное имя для этого символа - LATIN CAPITAL LETTER A.
    Версии JavaScript до 1.3.
    Unicode не поддерживается в версиях, более ранних, чем JavaScript 1.3.

    Вычисление переменных

    Вычисление переменных

    Переменная или элемент массива, которым не присвоено значение, имеют значение undefined. Результат вычисления переменной, не имеющей присвоенного значения зависит от того, как она была объявлена:
  • Если переменная без присвоенного значения была объявлена без использования var, вычисление приведёт к ошибке времени выполнения/runtime error.

  • Если переменная без присвоенного значения была объявлена с использованием var, вычисление даст значение undefined, или NaN - в числовом контексте.

  • Следующий код демонстрирует вычисление переменных, не имеющих присвоенного значения:
    function f1() {
    return y - 2;
    }
    f1() //Вызывает ошибку времени выполненияfunction f2() {
    return var y - 2;
    }
    f2() //возвращает NaN
    Можно использовать undefined, чтобы определить, имеет ли переменная значение. В следующем коде переменной input не присвоено значение, и оператор if вычисляется в true.
    var input;
    if(input === undefined){
    doThis();
    } else {
    doThat();
    }
    Значение undefined ведёт себя как false при использовании в качестве Булева значения. Например, следующий код выполняет функцию myFunction, поскольку элемент массива не определён:
    myArray=new Array()
    if (!myArray[0])
    myFunction()
    Если вычисляется переменная со значением null, то значение null работает как 0 в числовом контексте и как false - в Булевом контексте. Например:
    var n = null
    n * 32 //возвращает 0

    Замена символов/Escaping

    Замена символов/Escaping

    Для символов, не указанных в Таблице 2.1, предшествующий backslash игнорируется, за исключением знака кавычки и самого символа backslash (\).
    Вы можете вставить знак кавычки внутри строки, введя перед ним backslash. Это известно как escaping\замена знака кавычки. Например,
    var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service."
    document.write(quote)
    В результате будет выведено:
    He read "The Cremation of Sam McGee" by R.W. Service.
    Для включения в строку литерального backslash Вы обязаны escape-ировать backslash. Например, для присвоения строке пути к файлу c:\temp запишите так:
    var home = "c:\\temp"

    Значения

    JavaScript распознаёт следующие типы значений:

  • Числа, такие как 42 или 3.14159

  • Логические (Булевы) значения, это true или false

  • Строки, такие как "Howdy!"

  • null, специальное ключевое слово, обозначающее значение null; null является также примитивным значением. Поскольку JavaScript учитывает регистр символов, null это не то же самое, что Null, NULL или иной вариант.

  • undefined, свойство верхнего уровня/top-level, значением которого является undefined; undefined также является примитивным значением.

  • Этот сравнительно небольшой набор типов значений, или типов данных, даёт Вашим приложениям возможность выполнять различные функции. Отсутствует явное различие между целыми и реальными числами. Нет также типа данных date. Однако Вы может использовать объект Date и его методы для работы с датами.
    Объекты и функции также являются основными элементами языка. Можно считать объекты именованными контейнерами значений, а функции - процедурами, которые Ваше приложение выполняет.

    Клиентский JavaScript 1.3 Руководство

    Арифметические операции

    Арифметические операции

    Арифметические операции принимают в качестве операндов числовые значения (литералы или переменные) и возвращают единственное значение-результат. Стандартными арифметическими операциями являются операции сложения (+), вычитания (-), умножения (*) и деления (/). Эти операции работают так же, как и в большинстве других языков программирования, только операция / в JavaScript возвращает частное с плавающей точкой, а не округлённое частное, как в C или Java. Например:
    1/2 //возвращает 0.5 в JavaScript
    1/2 //возвращает 0 в Java
    Кроме того, JavaScript предоставляет арифметические операции, перечисленные в таблице.

    Битовые логические операции

    Битовые логические операции

    Концептуально битовые логические операции работают так:
  • Операнды конвертируются в 32-битные целые и выражаются серией битов (нулей и единиц).
  • Каждый бит первого операнда образует пару с соответствующим битом второго операнда: первый бит с первым, второй со вторым и т.д.

  • Операция применяется к каждой паре битов, и результат конструируется побитно.

  • Например, цифра 9 имеет двоичное/бинарное представление 1001, а цифра 15 - 1111. Поэтому результаты применения битовых операций к этим значениям будут такими:

  • 15 & 9 даст 9 (1111 & 1001 = 1001)

  • 15 | 9 даст 15 (1111 | 1001 = 1111)

  • 15 ^ 9 даст 6 (1111 ^ 1001 = 0110)


  • Битовые операции сдвига

    Битовые операции сдвига

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

    Битовые операции

    Битовые операции

    Битовые операции рассматривают свои операнды как 32-битные целые значения (последовательность 0 и 1), а не как 10-ричные, 16-ричные или 8-ричные числа. Например, десятеричное 9 имеет бинарное представление 1001. Битовые операции выполняются над такими двоичными представлениями, но возвращают стандартные числовые значения JavaScript.
    В таблице приведены битовые операции JavaScript.

    Delete

    delete

    Операция delete удаляет объект, свойство объекта или элемент по специфицированному индексу массива. Синтаксис таков:
    delete objectName
    delete objectName.property
    delete objectName[index]
    delete property // допустимо только в операторе with
    где objectName это имя объекта, property это существующее свойство, а index это целое число - местонахождение элемента в массиве.
    Четвёртая форма верна только в операторе with и удаляет свойство объекта.
    Вы можете использовать операцию delete для удаления переменных, объявленных неявно, но не для удаления переменных, объявленных оператором var.
    Если операция delete прошла успешно, она устанавливает свойство или элемент в значение undefined. Операция delete возвращает true, если операция возможна; она возвращает false, если операция невозможна.
    x=42
    var y= 43
    myobj=new Number()
    myobj.h=4 // создаёт свойство h
    delete x // возвращает true (можно удалить, если переменная х объявлена неявно)
    delete y // возвращает false (нельзя удалять, если объявлена с использованием var)
    delete Math.PI // возвращает false (нельзя удалять предопределенные свойства)
    delete myobj.h // возвращает true (можно удалять свойства, определённые пользователем)
    delete myobj // возвращает true (можно удалять объект, определённый пользователем)

    Логические операции

    Логические операции

    Логические операции обычно используются с Булевыми (логическими) значения; эти операции возвращают Булево значение. Однако операции && и || в действительности возвращают значение одного из специфицированных операндов, поэтому, если эти операции используются с не-Булевыми значениями, они могут вернуть не-Булево значение. Логические операции перечислены в таблице.

    New

    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. Справочник.

    Операции присвоения

    Операции присвоения

    Операция присвоения присваивает левому операнду значение правого операнда. Базовой операцией присвоения является "равно" (=), которая присваивает левому операнду значение правого операнда. То есть, x = y присваивает значение у переменной х.
    Другие операции присвоения являются аббревиатурами стандартных операций, как видно из таблицы.

    Операции сравнения

    Операции сравнения

    Операция сравнения сравнивает операнды и возвращает значение, основанное на true/верности сравнения. Операнды могут быть числами или строками. Строки сравниваются на основе стандартного лексикографического (словарного) порядка с использованием Unicode-значений. В таблице даны операции сравнения.

    Операции

    В этом разделе рассматриваются операции и приоритет выполнения. В JavaScript имеются следующие типы операций:
  • Операции присвоения

  • Операции сравнения
  • Арифметические

  • Битовые
  • Логические
  • Строковые

  • Специальные

  • В JavaScript есть как бинарные, так и унарные операции. Бинарная операция работает с двумя операндами, один - до знака операции, другой - после:
    операнд1 операция операнд2
    Например, 3+4 или x*y.
    Для унарной операции нужен один операнд, до или после знака операции:
    операция операнд
    или
    операнд операция
    Например, x++ или ++x.
    Кроме того, в JavaScript имеется тернарная условная операция. Тернарная операция требует трёх операндов.

    Операция , (запятая)

    операция , (запятая)

    Операция "запятая" (,) просто вычисляет два операнда и возвращает значение второго операнда. Эта операция используется в основном в цикле for, позволяя обновлять несколько переменных при каждом проходе цикла.
    Например, если a это 2-мерный массив из 10 элементов по измерению, следующий код использует операцию , для инкремента сразу двух переменных. Код печатает значения элементов по диагонали массива:
    for (var i=0, j=9; i <= 9; i++, j--)
    document.writeln("a["+i+","+j+"]= " + a[i,j])

    Функция validate проверяет свойство value

    Функция validate проверяет свойство value объекта, имея high и low-значения:
    function validate(obj, lowval, hival) {
    if ((obj.value < lowval) || (obj.value > hival))
    alert("Invalid Value!")
    }
    Вы можете вызывать validate в обработчике onChange каждого элемента формы, используя this для передачи в функцию элемента формы, как в следующем примере:
    Enter a number between 18 and 99:
    onChange="validate(this, 18, 99)">

    В сочетании со свойством form,

    В сочетании со свойством form, слово this может ссылаться на родительскую форму текущего объекта. В следующем примере форма myForm содержит Text-объект и кнопку. Если пользователь щёлкает по кнопке, в объект Text устанавливается имя формы. Обработчик onClick кнопки использует this.form для обращения к родительской форме myForm.

    Form name:

    onClick="this.form.text1.value=this.form.name">


    Приоритет операций

    Приоритет операций

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

    Сокращённый цикл вычисления

    Сокращённый цикл вычисления

    Поскольку логические выражения вычисляются слева направо, они проверяются на возможность "сокращённого/short-circuit" вычисления по следующим правилам:
  • false && anything ускоренно вычисляется в false.

  • true || anything ускоренно вычисляется в true.

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

    Специальные операции

    Специальные операции

    В JavaScript имеются следующие специальные операции:

  • условная операция
  • операция , (запятая)

  • delete
  • new

  • this
  • typeof

  • void


  • Строковые операции

    Строковые операции

    Помимо операций сравнения, которые могут использоваться со строковыми значениями, операция конкатенации (+) объединяет два строковых значения, возвращая строку, которая является результатом объединения двух строк-операндов. Например, "my " + "string" возвращает строку "my string".
    Операция-аббревиатура присвоения += также может использоваться для конкатенации строк. Например, если переменная mystring имеет значение "alpha", то выражение mystring += "bet" вычисляется в "alphabet" и это значение присваивается переменной mystring.

    Операции присвоения

    Таблица 3.1 Операции присвоения


    Аббревиатура
    Значение
    x += yx = x + y
    x -= yx = x - y
    x *= yx = x * y
    x /= yx = x / y
    x %= yx = x % y
    x <<= yx = x << y
    x >>= yx = x >> y
    x >>>= yx = x >>> y
    x &= yx = x & y
    x ^= yx = x ^ y
    x |= yx = x | y


    Операции сравнения

    Таблица 3.2 Операции сравнения

    Операция
    Описание
    Примеры, возвращающие true1
    Равно (==)Возвращает true, если операнды равны. Если два операнда имеют разные типы, JavaScript пытается конвертировать операнды в значения, подходящие для сравнения.3 == var1
    "3" == var1
    3 == '3'
    Не равно (!=)Возвращает true, если операнды не равны. Если два операнда имеют разные типы, JavaScript пытается конвертировать операнды в значения, подходящие для сравнения.var1 != 4
    var2 != "3"
    Строго равно (===)Возвращает true, если операнды равны и одного типа.3 === var1
    Строго не равно (!==)Возвращает true, если операнды не равны и/или не одного типа.var1 !== "3"
    3 !== '3'
    Больше (>)Возвращает true, если левый операнд больше правого операнда.var2 > var1
    Больше или равно (>=)Возвращает true, если левый операнд больше правого операнда или равен ему.var2 >= var1
    var1 >= 3
    Меньше (<)Возвращает true, если левый операнд меньше правого операнда.var1 < var2
    Меньше или равно (<=)Возвращает true, если левый операнд меньше правого операнда или равен ему.var1 <= var2
    var2 <= 5
    1В этих примерах принимается, что переменной var1 присвоено значение 3, а переменной var2 присвоено значение 4.


    Арифметические операции

    Таблица 3.3 Арифметические операции

    ОперацияОписаниеПример
    %
    (Целочисленный остаток)
    Бинарная операция. Возвращает целочисленный остаток от деления двух операндов.2 % 5 возвращает 2.
    ++
    (Инкремент)
    Унарная операция. Прибавляет 1 к операнду. Если используется как префикс (++x), возвращает значение операнда после прибавления 1; если используется как постфикс (x++), возвращает значение операнда до прибавления 1.Если x равен 3, то ++x устанавливает 4 в x и возвращает 4, а x++ устанавливает 4 в x и возвращает 3.
    --
    (Декремент)
    Унарная операция. Вычитает 1 из операнда. Возвращаемые значения аналогичны оператору инкремента.Если x равен 3, то --x устанавливает 2 в x и возвращает 2, а x++ устанавливает 2 в x и возвращает 3.
    -
    (Унарное отрицание)
    Унарная операция. Возвращает отрицание операнда.Если x равен 3, то -x возвращает -3.


    Битовые операции

    Таблица 3.4 Битовые операции


    Операция
    ИспользованиеОписание
    Иa & bВозвращает 1 в позиции каждого бита, где соответствующий бит обоих операндов равен 1.
    ИЛИa | bВозвращает 1 в позиции каждого бита, где соответствующий бит одного или обоих операндов равен 1.
    Исключающее ИЛИ/XORa ^ bВозвращает 1 в позиции каждого бита, где соответствующий бит одного, но не обоих, операндов равен 1.
    НЕ~ aИнвертирует биты операнда.
    Сдвиг влевоa << bСдвигает операнд a в бинарном представлении на b битов влево, заполняя справа нулями .
    Сдвиг вправо с сохранением знакаa >> bСдвигает операнд a в бинарном представлении на b битов вправо, отбрасывая смещённые биты.
    Сдвиг вправо с заполнением нулямиa >>> bСдвигает операнд a в бинарном представлении на b битов вправо, отбрасывая смещённые биты и заполняя слева нулями.


    Операции битового сдвига

    Таблица 3.5 Операции битового сдвига

    ОперацияОписаниеПример
    <<
    (Сдвиг влево)
    Эта операция сдвигает влево первый операнд на специфицированное вторым операндом количество битов. Излишние биты, сдвинутые влево, отбрасываются. Справа идёт заполнение нулями.9<<2 даёт 36, поскольку 1001, сдвинутое на 2 бита влево, становится 100100, что равно 36.
    >>
    (Сдвиг вправо с сохранением знака)
    Эта операция сдвигает вправо первый операнд на специфицированное вторым операндом количество битов. Излишние биты, сдвинутые вправо, отбрасываются. Копии левых битов вставляются слева.9>>2 даёт 2, поскольку 1001, сдвинутое на 2 бита вправо, становится 10, что равно 2. Аналогично -9>>2 даёт -3, поскольку знак сохраняется.
    >>>
    (Сдвиг вправо с заполнением нулями)
    Эта операция сдвигает вправо первый операнд на специфицированное вторым операндом количество битов. Излишние биты, сдвинутые вправо, отбрасываются. Слева идёт заполнение нулями.19>>>2 даёт 4, поскольку 10011, сдвинутое на 2 бита вправо, становится 100, то есть 4. Для неотрицательных чисел сдвиг вправо с заполнением нулями и сдвиг вправо с сохранением знака дают одинаковые результаты.


    Логические операции

    Таблица 3.6 Логические операции

    ОперацияИспользование
    Описание
    &&expr1 && expr2(Логическое И) Возвращает expr1, если может быть конвертировано в false; иначе возвращает expr2. Таким образом, при использовании с Булевыми значениями && возвращает true, если оба операнда true; иначе, возвращает false.
    ||expr1 || expr2(Логическое ИЛИ) Возвращает expr1, если может быть конвертировано в false; иначе возвращает expr2. Таким образом, при использовании с Булевыми значениями || возвращает true, если любой из операндов true; если оба false, возвращает false.
    ! !expr(Логическое НЕ) Возвращает false, если её единственный операнд может быть конвертирован в true; иначе возвращает true.

    Примерами выражений, которые могут быть конвертированы в false, являются выражения, вычисляемые в null, 0, пустую строку ("") или undefined.
    А это примеры операции && (logical AND).
    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
    Следующий код это примеры операции || (logical OR).
    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
    Следующий код это примеры операции ! (logical NOT).
    n1=!true // !t возвращает false
    n2=!false // !f возвращает true
    n3=!"Cat" // !t возвращает false

    This

    this

    Используйте ключевое слово this для обращения к текущему объекту. Вообще this ссылается на вызывающий объект в методе. Используйте this так:
    this[.propertyName]

    Typeof

    typeof

    Операция typeof используется двумя способами:
    1. typeof operand
    2. typeof (operand)
    Операция typeof возвращает строку - тип невычисленного операнда.

    operand это строка, переменная, ключевое слово или объект, тип которого возвращается. Скобки не обязательны.
    Предположим, Вы определяете следующие переменные:
    var myFun = new Function("5+2")
    var shape="round"
    var size=1
    var today=new Date()
    Операция typeof возвращает для этих переменных следующие результаты:
    typeof myFun is object
    typeof shape is string
    typeof size is number
    typeof today is object
    typeof dontExist is undefined
    Для ключевых слов true и null операция typeof возвращает:
    typeof true is boolean
    typeof null is object
    Для числа или строки операция typeof возвращает:
    typeof 62 is number
    typeof 'Hello world' is string
    Для значений свойств операция typeof возвращает тип значения, содержащегося в свойстве:
    typeof document.lastModified is string
    typeof window.length is number
    typeof Math.LN2 is number
    Для методов и функций операция typeof возвращает такие результаты:
    typeof blur is function
    typeof eval is function
    typeof parseInt is function
    typeof shape.split is function
    Для предопределённых объектов операция typeof возвращает:
    typeof Date is function
    typeof Function is function
    typeof Math is function
    typeof Option is function
    typeof String is function

    Удаление элементов массива

    Удаление элементов массива

    Если Вы удаляете элемент массива, размер массива не изменяется. Например, если Вы удаляете a[3], то a[4] продолжает оставаться a[4], а a[3] имеет значение undefined.
    Если операция delete удаляет элемент массива, этот элемент больше не присутствует в массиве. В следующем примере trees[3] удаляется операцией delete.
    trees=new Array("redwood","bay","cedar","oak","maple")
    delete trees[3]
    if (3 in trees) {
    // здесь операторы не выполняются
    }
    Если Вы хотите, чтобы элемент массива существовал, но имел неопределённое/undefined значение, используйте ключевое слово undefined вместо операции delete. В следующем примере элементу trees[3] присваивается значение undefined, но элемент массива продолжает существовать:
    trees=new Array("redwood","bay","cedar","oak","maple")
    trees[3]=undefined
    if (3 in trees) {
    // здесь операторы будут выполняться
    }

    Условная операция

    условная операция

    Условная операция это единственная операция JavaScript, принимающая три операнда. Эта операция может иметь одно из двух значений на основе выполнения условия. Синтаксис таков:
    condition ? val1 : val2
    Если condition true, операция выдаёт значение val1. Иначе она выдаёт значение val2. Вы можете использовать условную операцию там же, где используется стандартный оператор if.
    Например,
    status = (age >= 18) ? "adult" : "minor"
    Этот оператор присваивает значение "adult" переменной status, если age имеет значение 18 или более. Иначе переменной status присваивается значение "minor".

    Void

    void

    Операция void используется одним из следующих способов:
    1. void (expression)
    2. void expression
    Операция void специфицирует выражение, вычисляемое без возвращения значения.

    expression это вычисляемое выражение JavaScript. Скобки вокруг expression не обязательны, но их использование является хорошим стилем.
    Вы можете использовать операцию void для специфицирования выражения как гиперссылки. Выражение вычисляется, но не загружается вместо текущего документа.
    Следующий код создаёт гиперссылку, которая не выполняет никаких действий, если пользователь щёлкнет по ней. Если пользователь щёлкает по этой ссылке, void(0) вычисляется в 0, но это не вызывает никаких действий в JavaScript.
    Click here to do nothing
    Следующий код создаёт гиперссылку, которая отправляет форму на сервер, если пользователь щёлкнул по этой ссылке.

    Click here to submit


    Выражения

    Выражение\expression это правильный набор литералов, переменных, операций и выражений, который вычисляется в единственное значение; значение может быть числом, строкой или логическим значением.
    Концептуально имеются выражения двух типов: присваивающие значение переменной, и те, которые просто имеют значение. Например, выражение x= 7 присваивает переменной x значение 7. Это выражение вычисляется в 7. Такие выражения используют операции присвоения.

    Выражение 3 + 4 вычисляется в 7; оно выполняет операцию присвоения значения. Операции в таких выражениях называются просто операции.
    В JavaScript имеются следующие типы выражений:
  • Арифметические: вычисляются в число, например, 3.14159

  • Строковые: вычисляются в строку символов, например, "Fred" или "234"

  • Логические: вычисляются в true или false


  • Клиентский JavaScript 1.3 Руководство

    Использование простых патэрнов

    Использование простых патэрнов

    Простые патэрны состоят из символов, для которых ищется прямое совпадение. Например, патэрн /abc/ совпадает с комбинацией символов в строке только тогда, когда символы 'abc' появляются вместе и в указанном порядке. Такое совпадение будет найдено в строках "Hi, do you know your abc's?" и "The latest airplane designs evolved from slabcraft." В обоих случаях имеется совпадение с подстрокой 'abc'. В строке "Grab crab" совпадения нет, потому что она не содержит подстроки 'abc'.

    Использование скобок

    Использование скобок

    Скобки вокруг любой части патэрна регулярного выражения вызывают запоминание этой части совпавшей подстроки. После запоминания подстрока может быть вызвана для другого использования, как описано в разделе "Использование Совпадений Подстроки в Скобках".
    Например, патэрн /Chapter (\d+)\.\d*/ иллюстрирует совпадение дополнительных заменяющих и специальных символов и указывает, что эту часть патэрна нужно запомнить. Совпадает с точно символами 'Chapter ' и последующими одной или более цифрами (\d означает любую цифру, а + означает 1 или более раз), с последующей десятичной точкой (которая является сама по себе специальным символом; поэтому её предшествует \ , что означает, что патэрн обязан искать литеральный символ '.'), с последующим цифровым символом, 0 или более раз (\d означает цифру, * означает 0 или более раз). Кроме того, скобки используются для запоминания первых совпавших цифровых символов.
    Этот патэрн находит совпадение в "Open Chapter 4.3, paragraph 6", и '4' запоминается. Патэрн не находит совпадение в "Chapter 3 and 4", поскольку эта строка не содержит точку после '3'.

    Использование совпадений подстрок в скобках

    Использование совпадений подстрок в скобках

    Включение скобок в патэрн регулярного выражения вызывает запоминание соответствующего подсовпадения. Например, /a(b)c/ совпадает с символами 'abc' и запоминает 'b'. Для последующего вызова этих запомненных подсовпадений используйте свойства $1, ..., $9 объекта RegExp или элементы [1], ..., [n] объекта Array.
    Количество подстрок в скобках не ограничено. Предопределённый объект RegExp хранит последние 9 подстрок, а массив содержит всё, что найдено. Следующие примеры иллюстрируют использование совпадений подстрок в скобках.

    Пример 1.
    Следующий скрипт использует метод replace для переключения слов в строке. Для замещающего текста скрипт использует значения свойств $1 и $2.

    Будет выведено "Smith, John".
    Пример 2.
    В следующем примере RegExp.input устанавливается событием Change. В функции getInfo метод exec использует значение RegExp.input в качестве аргумента. Заметьте, что RegExp обязан быть присоединён как префикс к его свойствам $ (поскольку они появляются вне замещающей строки). (Пример 3 это более эффективный, хотя, может быть, и более завуалированный способ сделать то же самое.)
    Enter your first name and your age, and then press Enter.



    Пример 3.
    Это пример похож на Пример 2. Но вместо использования RegExp.$1 и RegExp.$2 этот пример создаёт массив и использует a[1] и a[2]. Здесь используется также сокращённая нотация для метода exec.
    Enter your first name and your age, and then press Enter.




    Использование специальных символов

    Использование специальных символов

    Если при поиске требуется выполнить нечто большее, чем простое совпадение, например, найти один или более символов b или найти пробелы, патэрн должен содержать специальные символы. Например, патэрн /ab*c/ совпадает с любой комбинацией символов, в которой после одиночного 'a' следуют ноль или более 'b' (* означает 0 или более вхождений предыдущего символа) и символ 'c'. В строке "cbbabbbbcdebc" этот патэрн совпадает с подстрокой 'abbbbc'.
    В таблице дан полный список - описание специальных символов, которые могут использоваться в регулярных выражениях.

    Изменение порядка в строке ввода

    Изменение порядка в строке ввода

    Это пример форматирования регулярных выражений и использования методов string.split() и string.replace(). Здесь зачищается грубо отформатированная строка ввода, содержащая имена (первое имя идёт первым), разделённые пробелом, табуляцией и одним символом "точка с запятой". Затем порядок имён разворачивается (последнее имя идёт первым) и список сортируется.


    Написание патэрна регулярного выражения

    Патэрн регулярного выражения состоит из простых символов, например, /abc/, или из комбинаций простых и специальных символов, как /ab*c/ или /Chapter(\d+)\.\d*/. В последнем примере имеются скобки, которые использованы как запоминающее устройство. Совпадение, сделанное этой частью патэрна, запоминается для последующего использования, как описано в разделе "Использование Совпадений Подстрок в Скобках".

    Далее идут пример использования регулярных

    Далее идут пример использования регулярных выражений.

    Работа в регулярными выражениями

    Регулярные выражения используются с методами test и exec объекта RegExp и с методами match, replace, search и split объекта String. Эти методы детально рассмотрены в книге
    Клиентский JavaScript.
    Справочник.

    Создание регулярного выражения

    Вы конструируете регулярное выражение одним из двух способов:

  • Используя инициализатор объекта:
  • re = /ab+c/
    Инициализаторы объектов выполняют компиляцию регулярного выражения при вычислении скрипта. Если регулярное выражение является константным, используйте инициализатор для повышения производительности. Инициализаторы объектов обсуждаются в разделе "Использование Инициализаторов Объектов".

  • Вызывая функцию-конструктор объекта RegExp:
  • re = new RegExp("ab+c")
    Использование функции-конструктора предоставляет компиляцию регулярного выражения на этапе прогона. Это делается, если известно, что патэрн регулярного выражения будет изменяться, или если Вы не знаете патэрн и получаете его из другого источника, такого как пользовательский ввод. После того как регулярное выражение определено, и если оно используется в скрипте и исходное значение изменяется, Вы можете использовать метод compile
    для компиляции нового регулярного выражения для более эффективного многократного использования.

    Специальные символы в регулярных выражениях

    Таблица 4.1 Специальные символы в регулярных выражениях


    Символ
    Значение
    \Один из следующих вариантов:

  • Для символов, которые обычно рассматриваются литерально, указывает, что следующий символ является специальным и не должен интерпретироваться литерально.
    Например, /b/ совпадает с символом 'b'. При помещении символа backslash перед b, то есть /\b/, символ становится специальным, обозначая границу слова.
  • Для символов, которые обычно рассматриваются как специальные, указывает что следующий символ не является специальным и должен интерпретироваться литерально.
    Например, * это специальный символ, который означает 0 или более совпадений с вхождением предыдущего символа; например, /a*/ означает 0 или более символов а. Для подстановки * литерально, поставьте передним backslash; например, /a\*/ совпадает с 'a*'.
  • ^Совпадает с началом ввода или строки.
    Например, /^A/ не совпадает с 'A' в строке "an A," но совпадает с первой А в строке "An A".
    $Совпадает с концом ввода или строки.
    Например, /t$/ не совпадает с 't' в "eater", но совпадает в "eat".
    *Предшествующий символ совпадает 0 или более раз.
    Например, /bo*/ совпадает с 'boooo' в "A ghost booooed" и с 'b' в "A bird warbled", но не совпадает в "A goat grunted".
    +Предшествующий символ совпадает 1 или более раз. Эквивалентно {1,}.
    Например, /a+/ совпадает с 'a' в "candy" and all the a's in "caaaaaaandy."
    ?Предшествующий символ совпадает 0 или 1 раз.
    Например, /e?le?/ совпадает с 'el' в "angel" и с 'le' в "angle."
    .(Десятичная точка) совпадает с любым одиночным символом, кроме символа новой строки.
    Например, /.n/ совпадает с 'an' и с 'on' в "nay, an apple is on the tree", но не с 'nay'.
    (x)Совпадает с 'x' и запоминает совпадение.
    Например, /(foo)/ совпадает (и запоминает) с 'foo' в "foo bar." Совпавшая подстрока может быть вызвана из результирующего массива элементов [1], ..., [n] или из свойств $1, ..., $9 предопределённого объекта RegExp.
    x|yСовпадает с 'x' или с 'y'.
    Например, /green|red/ совпадает с 'green' в "green apple" и с 'red' в "red apple."
    {n}Где n это положительное целое. Предшествующий символ совпадает точно n раз.
    Например, /a{2}/ не совпадает с 'a' в "candy", но совпадает со всеми 'a' в "caandy" и с первыми двумя 'a' в "caaandy."
    {n,}Где n это положительное целое. Предшествующий символ совпадает как минимум n раз.
    Например, /a{2,} не совпадает с 'a' в "candy", но совпадает со всеми 'a' в "caandy" и в "caaaaaaandy."
    {n,m}Где n и m это положительные целые. Предшествующий символ совпадает как минимум n и максимум m раз.
    Например, /a{1,3}/ не совпадает ни с чем в "cndy", совпадает с 'a' in "candy," первыми двумя 'a' в "caandy" и первыми тремя 'a' в "caaaaaaandy" Обратите внимание, что в "caaaaaaandy" совпадает только "aaa", хотя строка-оригинал содержит больше символов 'a'.
    [xyz]Набор символов. Совпадает с любым одним из символов патэрна. Вы можете специфицировать диапазон символов, используя дефис.
    Например, [abcd] эквивалентно [a-d]. Совпадает с 'b' в "brisket" и с 'c' в "ache".
    [^xyz]Отрицание набора символов. То есть совпадение со всем, кроме того, что находится в скобках. Вы можете специфицировать диапазон символов, используя дефис.
    Например, [^abc] это то же самое, что [^a-c]. Первоначально совпадает с 'r' в "brisket" и с 'h' в "chop".
    [\b]Совпадает с backspace. (Не путайте с \b.)
    \bСовпадает с границей слова, такой как пробел/space или символ новой строки. (Не путайте с [\b].)
    Например, /\bn\w/ совпадает с 'no' in "noonday"; /\wy\b/ совпадает с 'ly' in "possibly yesterday".
    \BСовпадает с не-границей слова.
    Например, /\w\Bn/ совпадает с 'on' в "noonday"; /y\B\w/ совпадает с 'ye' в "possibly yesterday".
    \cXГде X это управляющий символ. Совпадает с управляющим символом в строке.
    Например, /\cM/ совпадает с комбинацией control-M.
    \dСовпадает с цифрой. Эквивалентно [0-9].
    Например, /\d/ или /[0-9]/ совпадает с '2' в строке "B2 is the suite number".
    \DСовпадает с не-цифрой. Эквивалентно [^0-9].
    Например, /\D/ или /[^0-9]/ совпадает с 'B' в "B2 is the suite number".
    \fСовпадает с form-feed.
    \nСовпадает с linefeed.
    \rСовпадает с carriage return.
    \sСовпадает с одиночным пробельным символом, включая space, tab, form feed, line feed.

    Эквивалентно [ \f\n\r\t\v].
    Например, /\s\w*/ совпадает с ' bar' в "foo bar".
    \SСовпадает с одиночным символом, отличным от пробела. Эквивалентно [^ \f\n\r\t\v].
    Например, /\S\w*/ совпадает с 'foo' в "foo bar."
    \tСовпадает с tab.
    \vСовпадает с vertical tab.
    \wСовпадает с любым алфавитно-цифровым символом, включая символ подчёркивания. Эквивалентно [A-Za-z0-9_].
    Например, /\w/ совпадает с 'a' в "apple", с '5' в "$5.28" и с '3' в "3D."
    \W Совпадает с любым не-алфавитно-цифровым символом. Эквивалентно [^A-Za-z0-9_].
    Например, /\W/ или /[^$A-Za-z0-9_]/ совпадает с '%' в "50%."
    \nГде n это положительное целое. Обратная ссылка на последнее совпадение подстроки с n в скобках из регулярного выражения (с учётом левых скобок).
    Например, /apple(,)\sorange\1/ совпадает с 'apple, orange,' в "apple, orange, cherry, peach."

    Более сложный пример идёт далее после таблицы.
    Примечание: Если количество левых скобок меньше числа, специфицированного в \n, то \n считается восьмеричной escape-последовательностью, как описано в следующем ряду.
    \ooctal
    \xhex
    Где \ooctal это 8-ричное escape-значение или где \xhex это 16-ричное escape-значение. Даёт возможность внедрять ASCII-коды в регулярные выражения.


    Методы, использующие регулярные выражения

    Таблица 4.2 Методы, использующие регулярные выражения


    Метод
    Описание
    execМетод объекта RegExp, выполняющий поиск совпадения в строке. Возвращает массив информации.
    testМетод объекта RegExp, тестирующий на наличие совпадений в строке. Возвращает true или false.
    matchМетод объекта String, выполняющий поиск совпадения в строке. Возвращает массив информации, или null при отсутствии совпадения.
    searchМетод объекта String, тестирующий на наличие совпадений в строке. Возвращает индекс совпадения или -1, если поиск завершился неудачно.
    replaceМетод объекта String, выполняющий поиск совпадения в строке и заменяющий найденные подстроки замещающей подстрокой.
    splitМетод объекта String, использующий регулярное выражение или фиксированную строку для разделения строки на массив подстрок.

    Если Вам необходимо выяснить, найден ли патэрн в строке, используйте методы test или search; для получения большего количества информации (и более медленного выполнения) используйте методы exec или match.

    Если Вы используете exec или match и если совпадение найдено, эти методы возвращают массив и обновляют свойства ассоциированного объекта регулярного выражения и предопределённого объекта регулярного выражения, RegExp. Если совпадения нет, метод exec возвращает значение null (которое конвертируется в false).
    В следующем примере скрипт использует метод exec для поиска совпадения в строке:

    Если Вам не нужен доступ к свойствам регулярного выражения, можно создать myArray таким скриптом:

    Если Вы хотите иметь возможность рекомпиляции регулярного выражения, то вот ещё один скрипт:

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

    Результаты выполнения регулярного выражения

    Таблица 4.3 Результаты выполнения регулярного выражения


    Объект
    Свойство или ИндексОписание
    В данном примере
    myArrayСовпавшая строка и все запомненные подстроки.["dbbd", "bb"]
    indexИндекс с базой 0 совпадения в строке ввода.1
    inputСтрока-оригинал."cdbbdbsbz"
    [0]Последние совпавшие символы."dbbd"
    myRelastIndexИндекс, по которому находится начало следующего совпадения. (Это свойство устанавливается, только если регулярное выражение использует опцию g, описанную в разделе "Выполнение Глобального Поиска и Игнорирование Регистра Символов".)5
    sourceТекст патэрна."d(b+)d"
    RegExplastMatchПоследние совпавшие символы."dbbd"
    leftContextПодстрока, предшествующая самому последнему совпадению."c"
    rightContextПодстрока, идущая после самого последнего совпадения."bsbz"

    RegExp.leftContext и RegExp.rightContext могут быть высчитаны из других значений.
    RegExp.leftContext эквивалентно:
    myArray.input.substring(0, myArray.index)
    а RegExp.rightContext эквивалентно:
    myArray.input.substring(myArray.index + myArray[0].length)
    Как видно из второй формы этого примера, Вы можете использовать регулярное выражение, созданное инициализатором объекта, без присвоения его переменной. Если Вы это сделаете, каждое вхождение будет новым регулярным выражением. Поэтому, если Вы используете эту форму без присвоения значения, Вы не сможете получить доступ к свойствам этого регулярного выражения. Например, у Вас имеется такой скрипт:

    Он выводит:
    The value of lastIndex is 5
    Но если у Вас такой скрипт:

    Он выведет:
    The value of lastIndex is 0
    Появления /d(b+)d/g в этих двух операторах являются разными объектами регулярного выражения и, следовательно, имеют разные значения своих свойств lastIndex. Если Вам нужен доступ к свойствам регулярного выражения, созданного инициализатором объекта, Вы должны сначала присвоить его переменной.

    Выполнение глобального поиска и игнорирование регистра символов

    Выполнение глобального поиска и игнорирование регистра символов

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

    Для глобального поиска используйте флаг g.

    Для поиска без учёта регистра используйте флаг i.

    Эти флаги можно использовать вместе или по отдельности в любом порядке, и они включаются как часть регулярного выражения.
    Синтаксис для включения флага:
    re = /pattern/[g|i|gi]
    re = new RegExp("pattern", ['g'|'i'|'gi'])
    Заметьте, что флаги i и g являются неотъемлемой частью регулярного выражения. Они не могут быть добавлены и удалены позднее.
    Например, re = /\w+\s/g создаёт регулярное выражение, которое ищет один или более символов с последующим пробелом, и ищет такую комбинацию по всей строке.

    Это выведет ["fee ", "fi ", "fo "]. В данном примере Вы можете заменить строку:
    re = /\w+\s/g;
    на строку:
    re = new RegExp("\\w+\\s", "g");
    и получить тот же самый результат.

    Клиентский JavaScript 1.3 Руководство

    Оператор break

    Оператор break

    Оператор break используется для прерывания выполнения цикла, либо операторов switch или label.

  • Когда Вы используете break с операторами while, do-while, for или switch, оператор break немедленно прерывает самый внутренний цикл или switch и передаёт управление следующему оператору.

  • Когда Вы используете break внутри оператора label, он прерывает этот оператор и передаёт управление следующему оператору. Если Вы специфицировали label при вызове break, оператор break прерывает специфицированный оператор.

  • Синтаксис break выглядит так:
    1. break
    2. break [label]
    Первая форма прерывает самый внутренний цикл, switch или label; вторая форма прерывает специфицированный содержащий оператор label.
    Пример. Здесь происходит итерация по элементам массива, пока не будет найден индекс элемента, значением которого является theValue:
    for (i = 0; i < a.length; i++) {
    if (a[i] = theValue);
    break;
    }

    Оператор continue

    Оператор continue

    Оператор continue может использоваться для рестарта оператора while, do-while, for или label.

  • В операторах while или for, оператор continue прерывает текущий цикл и начинает новую итерацию (проход) цикла. В отличие от break, continue не прерывает полностью выполнение цикла. В цикле while он перескакивает на condition. В цикле for он перескакивает на increment-expression.

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

  • Синтаксис оператора continue выглядит так:
    1. continue
    2. continue [label]

    Оператор do...while

    Оператор do...while

    Оператор do...while повторяется, пока специфицированное выражение не станет false. Оператор do...while выглядит так:
    do {
    statement
    } while (condition)
    statement выполняется как минимум один раз, так как находится перед проверяемым условием. Если condition возвращает true, цикл выполняется ещё раз. В конце каждого прохода проверяется условие. Если condition возвращает false, выполнение останавливается и управление передаётся оператору, идущему после do...while.
    Пример. В следующем примере цикл do итерирует как минимум один раз, пока i не станет меньше 5.
    do {
    i+=1;
    document.write(i);
    } while (i<5);

    Оператор for...in

    Оператор 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] + "
    "
    }
    result += "
    "
    return result
    }
    Для объекта car со свойствами make и model, result будет:
    car.make = Ford
    car.model = Mustang

    Оператор for

    Оператор for

    Оператор for повторяется, пока специфицированное условие не станет false. JavaScript-цикл for похож на аналогичные циклы Java и C. Оператор for выглядит так:
    for ([initialExpression]; [condition]; [incrementExpression]) {
    statements
    }
    При выполнении цикла for происходит следующее:

  • Выполняется инициализирующее выражение initial-expression, если имеется. Это выражение обычно инициализирует один или более счётчиков цикла, но синтаксис допускает выражения любой сложности.

  • Выражение condition вычисляется. Если condition даёт true, цикл выполняется. Если condition равно false, цикл for прерывается.
  • Выполняются statements/операторы.

  • Выполняется выражения обновления incrementExpression, и управление возвращается к шагу 2.

  • Пример. Эта функция содержит оператор for, подсчитывающий количество выбранных опций в прокручиваемом списке (объекте Select, который позволяет делать множественный выбор). Оператор for объявляет переменную i и инициализирует её значением 0 (нуль). Если i меньше количества опций объекта Select, выполняется следующий оператор if, а i увеличивается на 1 при каждом прохождении цикла.

    Choose some music types, then click the button below:


    onClick="alert ('Number of options selected: ' + howMany(document.selectForm.musicTypes))">


    Оператор if...else

    Оператор if...else

    Оператор if используется для выполнения определённых операторов, если логическое условие true; не обязательный блок else выполняется, если условие false. Оператор if выглядит так:
    if (condition) {
    statements1
    }
    [else {
    statements2
    } ]
    condition это может быть любое выражение JavaScript, которое вычисляется в true или false. Выполняемые операторы это любые операторы JavaScript, включая вложенные if. Если Вы хотите использовать более одного оператора после операторов if или else, Вы обязаны заключать их в фигурные скобки {}.
    Не путайте примитивные Boolean-значения true и false со значениями true и false объекта Boolean. Любой объект, значением которого не является undefined или null, включая объект Boolean со значением false, вычисляется в true, когда передаётся в условный оператор. Например:
    var b = new Boolean(false);
    if (b) // это условие вычисляется в true
    Пример. В следующем примере функция checkData возвращает true, если количество символов в объекте Text равно трём; иначе выводит диалог alert и возвращает 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 предоставляет оператор с идентификатором, что позволяет обратиться к нему в программе. Например, Вы можете использовать label для идентифицирования цикла, а затем использовать break или continue для указания момента, когда программа должна прервать выполнение цикла или начать новую итерацию.
    Синтаксис оператора label примерно такой:
    label :
    statement
    Значение label это любой идентификатор JavaScript, не являющийся зарезервированным словом. statement\оператор , идентифицируемый Вами с помощью label, может быть любого типа.
    Пример. Здесь label markLoop идентифицирует цикл while.
    markLoop:
    while (theMark == true)
    doSomething();
    }

    Оператор switch

    Оператор switch

    Оператор switch позволяет вычислять выражение и пытается найти совпадение значения выражения с оператором label. Если совпадение найдено, программа выполняет ассоциированный оператор. Оператор switch выглядит так:
    switch (expression){
    case label :
    statement;
    break;
    case label :
    statement;
    break;
    ...
    default : statement;
    }
    Программа сначала ищет label/метку, совпадающую по значению с выражением, а затем выполняет ассоциированный оператор. Если совпадающий label не найден, программа ищет не обязательный оператор по умолчанию и, если он найден, выполняет ассоциированный оператор. Если оператор по умолчанию/default statement на найден, программа продолжает выполняться с оператора, идущего после конца switch.
    Не обязательный оператор break, ассоциируемый с каждым case, гарантирует, что программа прервёт выполнение блока 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.
    ");
    break;
    case "Apples" :
    document.write("Apples are $0.32 a pound.
    ");
    break;
    case "Bananas" :
    document.write("Bananas are $0.48 a pound.
    ");
    break;
    case "Cherries" :
    document.write("Cherries are $3.00 a pound.
    ");
    break;
    default :
    document.write("Sorry, we are out of " + i + ".
    ");
    }document.write("Is there anything else you'd like?
    ");

    Оператор while

    Оператор while

    Оператор while выполняется, пока специфицированное условие вычисляется в true. Оператор while выглядит так:
    while (condition) {
    statements
    }
    Если condition становится false, операторы внутри цикла перестают выполняться и управление передаётся оператору, идущему после цикла.
    Проверка условия/condition выполняется перед началом каждого цикла. Если condition возвращает true, операторы выполняются и условие проверяется снова. Если condition возвращает false, выполнение прекращается и управление передаётся оператору, идущему после цикла while.

    Оператор with

    Оператор with

    Оператор with устанавливает объект по умолчанию для блока операторов. JavaScript ищет неквалифицированные имена в на боре операторов для определения, являются ли имена свойствами объекта пор умолчанию. Если неквалифицированное имя совпадает со свойством, то свойство используется в операторе; иначе используется локальная или глобальная переменная.
    Оператор with выглядит так:
    with (object){
    statements
    }
    Пример. Оператор with специфицирует, что объект Math является объектом по умолчанию. Оператор, идущий после оператора with, обращается к свойству PI и методам cos и sin без специфицирования объекта. JavaScript принимает Math как объект для этих свойств.
    var a, x, y
    var r=10
    with (Math) {
    a = PI * r * r
    x = r * cos(PI)
    y = r * sin(PI/2)
    }

    Операторы циклов

    Цикл/loop это набор команд, которые выполняются неоднократно, пока не будет выполнено специфицированное условие. JavaScript поддерживает операторы циклов for, do while, while и label (label сам по себе не является оператором цикла, но часто используется с этими операторами). Кроме того, Вы можете использовать операторы break и continue с операторами циклов.
    Ещё один оператор, for...in, выполняет операторы циклически, но используется при работе с объектами. См. "Операторы Манипуляций с Объектами".

    Операторы манипулирования объектами

    JavaScript использует операторы for...in и with для работы с объектами.

    Следующий цикл while итерирует, пока

    Следующий цикл while итерирует, пока n меньше 3:
    n = 0
    x = 0
    while( n < 3 ) {
    n ++
    x += n
    }
    При каждой итерации выполняется инкремент n и обновляется значение x. Следовательно, x и n получают следующие значения:

  • После первого прохода: n = 1 и x = 1

  • После второго прохода: n = 2 и x = 3

  • После третьего прохода: n = 3 и x = 6

  • После третьего прохода условие n < 3 больше не true, поэтому цикл прерывается.

    с оператором continue выполняется, если

    здесь цикл while с оператором continue выполняется, если i имеет значение 3. Таким образом, n получает значения 1, 3, 7 и 12.
    i = 0
    n = 0
    while (i < 5) {
    i++
    if (i == 3)
    continue
    n += i
    }

    помеченный checkiandj, содержит оператор, помеченный

    Оператор, помеченный checkiandj, содержит оператор, помеченный checkj. Если обнаружен continue, программа прерывает текущую итерацию checkj и начинает следующую. Каждый раз при обнаружении continue оператор checkj реитерирует, пока его условие не возвратит false. Если возвращено false, выполняется остаток оператора checkiandj и checkiandj реитерирует, пока его условие не возвратит false. Если возвращено false, программа продолжает выполнение с оператора, идущего после checkiandj.
    Если continue имеет метку checkiandj, программа продолжит выполнение от верха оператора checkiandj.
    checkiandj :
    while (i<4) {
    document.write(i + "
    ");
    i+=1;
    checkj :
    while (j>4) {
    document.write(j + "
    ");
    j-=1;
    if ((j%2)==0);
    continue checkj;
    document.write(j + " is odd.
    ");
    }
    document.write("i = " + i + "
    ");
    document.write("j = " + j + "
    ");
    }

    Бесконечный цикл.

    Проверяйте, что условие в цикле рано или поздно станет false; иначе цикл никогда не закончится. Операторы следующего цикла while выполняются бесконечно, поскольку condition никогда не станет false:
    while (true) {
    alert("Hello, world") }

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

    Условный оператор это набор команд, выполняемый, если специфицированное true. JavaScript поддерживает два условных оператора : if...else и switch.

    Клиентский JavaScript 1.3 Руководство

    Функции Number и String

    Функции Number и String

    Функции Number и String позволяют конвертировать объект в число или строку. Синтаксис таков:
    Number(objRef)
    String(objRef)
    где objRef это ссылка на объект.
    В следующем примере Date-объект конвертируется в читабельную строку.
    D = new Date (430054663215)
    // возвращает
    // "Thu Aug 18 04:37:43 GMT-0700 (Pacific Daylight Time) 1983"
    x = String(D)

    Функции parseInt и parseFloat

    Функции parseInt и parseFloat

    Две "parse"-функции, parseInt и parseFloat, возвращают числовое значение при получении строкового аргумента.
    Синтаксис parseFloat таков:
    parseFloat(str)
    где parseFloat разбирает свой аргумент, строку str, и пытается возвратить число с плавающей точкой. Если она обнаруживает символ, отличный от знака (+ или -), числа (0-9), десятичной точки или экспоненты, она возвращает значение, разобранное до этого места, и игнорирует этот символ и все последующие символы. Если первый символ не может быть конвертирован в число, функция возвращает значение "NaN" (не-число).
    Синтаксис parseInt таков:
    parseInt(str [, radix])
    parseInt разбирает первый аргумент, строку str, и пытается возвратить целое число со специфицированной radix (базой), обозначаемой вторым не обязательным аргументом radix. Например, radix 10 указывает на конвертацию десятеричного числа, 8 -восьмеричного, 16 - шестнадцатеричного, и так далее. При radix более 10 буквы латинского алфавита используются для обозначения цифр больше 9. Например, для 16-ричных чисел (база 16), используются английские буквы от A до F.
    Если parseInt обнаруживает символ, не являющийся цифрой в специфицированном radix, она игнорирует этот и все последующие символы и возвращает целочисленное значение, разобранное до этого места. Если первый символ не может быть конвертирован в число со специфицированной базой, функция возвращает "NaN." Функция parseInt усекает строку до целочисленных значений.

    Функция eval

    Функция eval

    Функция eval вычисляет строку кода JavaScript без ссылки на определённый объект. Синтаксис eval таков:
    eval(expr)
    где expr это вычисляемая строка.
    Если строка представляет выражение, eval вычисляет это выражение. Если аргумент представляет собой один или несколько операторов JavaScript, eval выполняет эти операторы. Не вызывайте eval для вычисления арифметических выражений; JavaScript вычисляет арифметические выражения автоматически.

    Функция isFinite

    Функция isFinite

    Функция isFinite вычисляет аргумент, чтобы определить, является ли он конечным числом. Синтаксис isFinite:
    isFinite(number)
    где number это вычисляемое число.
    Если аргумент имеет значения NaN, положительная или отрицательная бесконечность, то этот метод возвращает false, иначе возвращает true.
    Следующий код проверяет клиентский ввод и определяет, является ли он конечным числом.
    if(isFinite(ClientInput) == true)
    {
    /* некоторые специальные шаги */
    }

    Функция isNaN

    Функция isNaN

    Функция isNaN вычисляет аргумент, чтобы определить, является ли он "NaN" (не-числом). Синтаксис isNaN:
    isNaN(testValue)
    где testValue это значение, которое Вы хотите обсчитать.
    Функции parseFloat и parseInt возвращают "NaN", если они вычисляют значение, которое не является числом. isNaN возвращает true, если передано "NaN", и false - в ином случае.
    Следующий код вычисляет floatValue и определяет, является ли оно числом, а затем вызывает соответствующую процедуру:
    floatValue=parseFloat(toFloat)
    if (isNaN(floatValue)) {
    notFloat()
    } else {

    isFloat()
    }

    Использование массива arguments

    Аргументы обрабатываются в массиве. В функции Вы можете адресовать параметры, передаваемые ей:
    arguments[i]
    functionName.arguments[i]
    где i это порядковый номер аргумента, начиная с 0. Таким образом, первый аргумент, передаваемый функции, это arguments[0]. Общее число аргументов указывается свойством arguments.length.
    Используя массив arguments, Вы можете вызвать функцию с большим количеством аргументов, чем объявлено в формальном определении. Это часто используется, если заранее не известно точное количество аргументов, передаваемых функции. Вы можете использовать arguments.length для определения количества аргументов, реально передаваемых функции, а затем работать с каждым аргументом с использованием массива arguments.
    Например, рассмотрим функцию, которая объединяет несколько строк. Единственным формальным аргументом для этой функции является строка, которая специфицирует символы, разделяющие объединяемые элементы. Функция определена так:
    function myConcat(separator) {
    result="" // инициализирует список

    // итерирует по аргументам
    for (var i=1; i
    result += arguments[i] + separator
    }

    return result
    }
    Вы можете передать этой функции любое количество аргументов, и она создаст список, используя каждый аргумент как элемент списка.
    // возвращает "red, orange, blue, "
    myConcat(", ","red","orange","blue")
    // возвращает "elephant; giraffe; lion; cheetah;"

    myConcat("; ","elephant","giraffe","lion", "cheetah")
    // возвращает "sage. basil. oregano. pepper. parsley. "
    myConcat(". ","sage","basil","oregano", "pepper", "parsley")
    См. статью об объекте Function в книге
    Клиентский JavaScript. Справочник.

    Определение функций

    Определение функции состоит из ключевого слова function и:
  • имени функции

  • списка аргументов, заключённых в скобки и разделённых запятыми

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

  • Вы должны определять все Ваши функции в HEAD/шапке страницы, чтобы при её загрузке пользователем функции загружались в первую очередь. Иначе пользователь может выполнить действие, когда страница ещё загружается, и включить обработчик и вызвать функцию, которая ещё не определена, что приведёт к возникновению ошибки.
    Например, следующий код определяет простую функцию square:
    function square(number) {
    return number * number;
    }
    Функция square принимает один аргумент number. Эта функция состоит из одного оператора, указывающего возвращаемое значение - аргумент функции, умноженный сам на себя. Оператор return специфицирует значение, возвращаемое функцией.
    return number * number
    Все параметры передаются функциям по значению; значение передаётся функции, но если функция изменяет значение параметра, это изменение не отражается глобально или в вызывающей функции. Однако, если Вы передаёте функции объект в качестве параметра и функция изменяет свойства объекта, это изменение видно́ вне функции, как показано в примере:
    function myFunc(theObject) {
    theObject.make="Toyota"
    }


    mycar = {make:"Honda", model:"Accord", year:1998}
    x=mycar.make // возвращает Honda
    myFunc(mycar) // передаёт объект mycar функции
    y=mycar.make // возвращает Toyota (prop было изменено функцией)
    Помимо описанного здесь определения функции, Вы можете также определять объекты Function, как показано в разделе "Объект Function".
    Метод это функция, ассоциированная с объектом. Вы может узнать больше об объектах и методах в Главе 7 "Работа с Объектами".

    Предопределённые функции

    В JavaScript есть несколько предопределённых функций:
  • eval

  • isFinite

  • isNaN

  • parseInt и parseFloat

  • Number и String

  • escape и unescape

  • В следующих разделах рассматриваются эти функции. См. также книгу
    Клиентский JavaScript. Справочник.

    Вызов функций

    В приложениях для Navigator'а Вы можете использовать (или вызывать) любую функцию, определённую на текущей странице. Вы можете также использовать функции, определённые другими именованными окнами или фрэймами.
    Определение функции не вызывает её выполнения. Определение функции просто именует функцию и специфицирует, что́ выполняется при вызове функции. Вызов функции реально выполняет специфицированные акции с указанными параметрами. Например, если Вы определили функцию square, Вы можете вызвать её так:
    square(5)
    Это оператор вызова функции с аргументом 5. Функция выполняет свои операторы и возвращает значение 25.
    Аргументы функции не ограничиваются только числами и строками. Вы можете также передавать в функцию объекты. Функция show_props (определённая в разделе "Объекты и Свойства") это пример функции, принимающей в качестве аргумента объект.
    Функция может быть рекурсивной, то есть вызывать сама себя. Например, вот функция вычисления факториалов:
    function factorial(n) {
    if ((n == 0) || (n == 1))

    return 1
    else {

    result = (n * factorial(n-1) )
    return result

    }
    }
    Вы можете вычислить факториалы значений от 1 до 5:
    a=factorial(1) // возвращает 1
    b=factorial(2) // возвращает 2
    c=factorial(3) // возвращает 6
    d=factorial(4) // возвращает 24
    e=factorial(5) // возвращает 120

    Клиентский JavaScript 1.3 Руководство

    Двухмерные массивы

    Двухмерные массивы

    Следующий код создаёт двухмерный массив:
    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+"]"
    }
    }
    Следующий код выводит массив:
    for (i=0; i < 4; i++) {
    str = "Row "+i+":"
    for (j=0; j < 4; j++) {
    str += a[i][j]
    }
    document.write(str,"")
    }
    Будет выведено:
    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]

    Индексирование свойств объекта

    Индексирование свойств объекта

    В JavaScript 1.0 Вы можете обратиться к свойствам объекта по имени или по индексу. В JavaScript 1.1 или позднее, однако, если Вы первоначально определили свойство по имени, Вы обязаны всегда обращаться к нему по имени и, если Вы первоначально определили свойство по индексу, Вы обязаны всегда обращаться к нему по индексу.
    Это применяется при создании объекта и его свойств функцией-конструктором, как в предыдущем примере с типом объектов сar, и при определении индивидуальных свойств явным образом (например, myCar.color = "red"). Так, если Вы определяет первоначально свойства объекта индексированием, как myCar[5] = "25 mpg", Вы в дальнейшем обращаетесь к свойству myCar[5].
    Исключением из этого правила является объект, отражённый из HTML, такой как массив forms. Вы можете всегда обратиться к объектам в этих массивах по порядковому номеру (в зависимости от места в документе) или по именам (если определены). Например, если второй тэг
    в документе имеет в атрибуте NAME значение "myForm", Вы можете обратиться к форме document.forms[1] or document.forms["myForm"] или document.myForm.

    Использование функции-конструктора

    Использование функции-конструктора

    Альтернативно можно создавать объект в два этапа:

  • Определить тип объекта, написав функцию-конструктор.

  • Создать экземпляр объекта с помощью операции new.

  • Для того чтобы определить тип объекта, создайте функцию для типа объекта, которая специфицирует имя, свойства и методы. Например, Вы хотите создать тип объекта для автомобилей/cars. Вы называете тип объекта car и хотите, чтобы у него были свойства make, model, year и color. Для реализации этого Вы должны написать следующую функцию:
    function car(make, model, year) {
    this.make = make
    this.model = model
    this.year = year
    }
    Обратите внимание на использование this для присвоения значений свойствам объекта на основе значений, передаваемых в функцию.
    Теперь Вы можете создать объект mycar:
    mycar = new car("Eagle", "Talon TSi", 1993)
    Этот оператор создаёт объект mycar и присваивает специфицированные значения его свойствам. Тогда значением mycar.make будет строка "Eagle", mycar.year это целое число 1993 и так далее.
    Вы можете создать любое количество объектов car через вызов new. Например,
    kenscar = new car("Nissan", "300ZX", 1992)
    vpgscar = new car("Mazda", "Miata", 1990)
    Объект может иметь свойство, которое само является объектом. Например, Вы определяете объект person:
    function person(name, age, sex) {
    this.name = name
    this.age = age
    this.sex = sex
    }
    и инстанциируете два новых person-объекта:
    rand = new person("Rand McKinnon", 33, "M")
    ken = new person("Ken Jones", 39, "M")
    Затем Вы можете переписать определение car и включить в него свойство owner, которое принимает person-объект:
    function car(make, model, year, owner) {
    this.make = make
    this.model = model
    this.year = year
    this.owner = owner
    }
    Теперь можно инстанциировать новые объекты:
    car1 = new car("Eagle", "Talon TSi", 1993, rand)
    car2 = new car("Nissan", "300ZX", 1992, ken)
    Обратите внимание, что вместо передачи литеральной строки или целочисленного значения при создании новых объектов, эти операторы передают объекты rand и ken как аргументы для owner. Затем, если Вы хотите вычислить имя владельца автомобиля car2, Вы можете получить доступ к следующему свойству:
    car2.owner.name
    Заметьте, что Вы всегда можете добавить свойство к ранее определённому объекту. Например, оператор
    car1.color = "black"
    добавляет свойство color объекту car1 и присваивает ему значение "black." Однако это не влияет на все другие объекты. Для добавления свойства всем объектам данного типа Вы должны добавить свойство в определение типа объекта car.

    Использование инициализаторов объектов

    Использование инициализаторов объектов

    Помимо создания объектов с использованием функции-конструктора, Вы можете создавать объекты с использованием инициализатора объекта. Использование инициализаторов объектов иногда называют созданием объектов с помощью литеральной нотации. "Инициализатор объекта" составлен в терминологии C++.
    Синтаксис объекта, использующего инициализатор объекта, таков:
    objectName = {property1:value1, property2:value2,..., propertyN:valueN}
    где objectName это имя нового объекта, каждое propertyI это идентификатор (имя, число или строковой литерал), а каждое valueI это выражение, значение которого присваивается свойству propertyI.

    objectName и присвоение не обязательны. Если Вам не нужно ссылаться на данный объект, Вы можете не присваивать его переменной.
    Если объект создаётся инициализатором в скрипте верхнего уровня, JavaScript интерпретирует этот объект всякий раз при вычислении выражения, содержащего литерал объекта. К тому же инициализатор, используемый в функции, создаётся при каждом вызове функции.
    Этот оператор создаёт объект и присваивает его переменной x, если, и только если, выражение cond - true.
    if (cond) x = {hi:"there"}
    Следующий пример создаёт myHonda с тремя свойствами. Заметьте, что свойство engine является также объектом со своими собственными свойствами.
    myHonda = {color:"red",wheels:4,engine:{cylinders:4,size:2.2}}
    Вы можете также использовать инициализаторы объектов для создания массивов. См. "Литералы Массива".

    JavaScript 1.1 и предыдущие версии.

    Вы не можете использовать инициализаторы объектов. Вы можете создавать объекты только путём использования функций-конструкторов или функцией, предоставляемой другим объектом для этой цели. См. "Использование Функции-Конструктора".

    Использование объекта Date: пример

    Использование объекта 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)
    temp += ((minute < 10) ? ":0" : ":") + minute
    temp += ((second < 10) ? ":0" : ":") + second
    temp += (hour >= 12) ? " P.M." : " A.M."
    return temp
    }
    Функция JSClock сначала создаёт новый Date-объект time; поскольку аргументы не заданы, объект создаётся с текущей датой и временем. Затем методы getHours, getMinutes и getSeconds присваивают значения текущих часа, минут и секунд переменным hour, minute и second.
    Следующие четыре оператора строят строковое значение на основе этого времени.
    Первый оператор создаёт переменную temp, присваивая ей значение условного выражения; если hour больше 12, (hour - 13), иначе просто hour.
    Следующий оператор присоединяет значение minute к temp. Если значение minute меньше 10, условное выражение прибавляет строку с предшествующим 0; иначе добавляет строку с разделяющим двоеточием. Затем оператор присоединяет значение секунд к temp тем же способом.
    Наконец, условное выражение присоединяет "PM" к temp, если hour равно или больше 12; иначе присоединяет "AM" к temp.

    Использование this для ссылок на объект

    Использование this для ссылок на объект

    В JavaScript имеется специальное слово this, которое можно использовать в методе для обращения к текущему объекту. Например, у Вас имеются: функция validate для проверки свойства value объекта, объект и значения high и low:
    function validate(obj, lowval, hival) {
    if ((obj.value < lowval) || (obj.value > hival))
    alert("Invalid Value!")
    }
    Затем Вы можете вызывать validate в обработчике события onChange каждого элемента формы, используя this для передачи ему элемента формы, как в следующем примере:
    onChange="validate(this, 18, 99)">
    В общем случае, this ссылается в методе на вызывающий объект.
    При сочетании со свойством form, this может ссылаться на родительскую форму текущего объекта. В следующем примере, форма myForm содержит Text-объект и кнопку. Когда пользователь нажимает кнопку, в значение Text-объекта устанавливается имя формы. Обработчик onClick кнопки использует this.form для обращения к родительской форме, myForm.

    Form name:

    onClick="this.form.text1.value=this.form.name">


    Массивы и регулярные выражения

    Массивы и регулярные выражения

    Если массив является результатом совпадения регулярного выражения и строки , этот массив возвращает свойства и элементы, которые предоставляют информацию о совпадении. Массив является тогда return-значением regexp.exec, string.match и string.replace. Об использовании массивов с регулярными выражениями см. Главу 4 "Регулярные Выражения".

    Методы объекта Array

    Методы объекта 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".

    Методы объекта Date

    Методы объекта Date

    Методы объекта Date для работы с датами и временем распадаются на следующие обширные категории:
  • "set"-методы для установки значений объектов Date.

  • "get"-методы для получения значений даты и времени из объектов Date.

  • "to"-методы для возвращения строковых значений из объектов Date.

  • parse и UTC-методы для разбора Date-строк.

  • Методами "get" и "set" Вы можете получать и устанавливать значения для секунд, минут, часа, дня недели, числа месяца, месяца и года. Имеется метод getDay, который возвращает день недели, но нет па́рного метода setDay, поскольку день недели устанавливается автоматически. Эти методы используют целые числа для представления этих значений:
  • Секунды и минуты: от 0 до 59

  • Час: от 0 до 23

  • День недели: от 0 (Sunday) до 6 (Saturday)

  • Число месяца: от 1 до 31

  • Месяц: от 0 (January) до 11 (December)

  • Год: годы после 1900

  • Например, Вы определили дату:
    Xmas95 = new Date("December 25, 1995")
    Тогда Xmas95.getMonth() возвращает 11, а Xmas95.getFullYear() возвращает 95.
    Методы getTime и setTime используются для сравнения дат. Метод getTime возвращает количество миллисекунд, прошедших после January 1, 1970, 00:00:00 для Date-объекта.
    Например, следующий код выводит количество дней оставшихся в текущем году:
    today = new Date()
    endYear = new Date(1995,11,31,23,59,59,999) // устанавливает день и месяц
    endYear.setFullYear(today.getFullYear()) // устанавливает в year текущий год
    msPerDay = 24 * 60 * 60 * 1000 // количество миллисекунд в сутках
    daysLeft = (endYear.getTime() - today.getTime()) / msPerDay
    daysLeft = Math.round(daysLeft) //возвращает количество оставшихся в году дней
    Этот пример создаёт Date-объект today, который содержит текущую дату. Затем создаётся Date-объект endYear в него устанавливается значение текущего года. Далее, с использованием количества миллисекунд в сутки, вычисляется количество дней между текущей датой и endYear, с использованием getTime, которое затем округляется до целого количества суток.
    Метод parse используется для присвоения значений из строк с датой существующим Date-объектам. Например, следующий код использует parse и setTime для присвоения значения даты объекту IPOdate:
    IPOdate = new Date()
    IPOdate.setTime(Date.parse("Aug 9, 1995"))

    Наполнение массива

    Наполнение массива

    Вы можете наполнить массив, присвоив значения его элементам. Например,
    emp[1] = "Casey Jones"
    emp[2] = "Phil Lesh"
    emp[3] = "August West"
    Вы может наполнить массив также при его создании:
    myArray = new Array("Hello", myVar, 3.14159)

    Объект Array

    Объект Array

    В JavaScript нет типа данных array (массив). Однако Вы может использовать предопределённый объект Array и его методы для работы с массивами в Ваших приложениях. Объект Array имеет методы для работы с массивами: объединения, разворачивания и сортировки. Он имеет свойство для определения размера массива и другие свойства для использования с регулярными выражениями.
    Массив это упорядоченный набор значений, к которым Вы обращаетесь по индексу или по имени. Например, у Вас имеется массив emp, в котором содержатся имена служащих, индексированные числом. Так, emp[1] это служащий номер 1, emp[2] - служащий номер 2 и так далее.

    Объект Boolean

    Объект Boolean

    Объект Boolean является оболочкой вокруг примитивного типа данных Boolean. Используйте следующий синтаксис для создания Boolean-объекта:
    booleanObjectName = new Boolean(value)
    Не путайте примитивные Boolean-значения true и false со значениями true и false объекта Boolean. Любой объект, значение которого не undefined или null, и не объект Boolean со значением false, вычисляется в true, когда передаётся в условный оператор. См. "Оператор if...else".

    Объект Date

    Объект Date

    В JavaScript нет типа данных data. Однако можно использовать объект Date и его методы для работы с датами и временем. Объект Date имеет большое количество методов для установки, получения и обслуживания дат.
    Он не имеет свойств.
    JavaScript обрабатывает даты аналогично Java. Эти два языка имеют много одинаковых методов для дат и хранят даты как количество миллисекунд относительно 1 января 1970 года, 00:00:00.
    Диапазон объекта Date от -100,000,000 до 100,000,000 дней относительно 01 January, 1970 UTC.
    Для создания Date-объекта:
    dateObjectName = new Date([parameters])
    где dateObjectName это имя создаваемого Date-объект; это может быть новый объект или свойство существующего объекта.
    Значение parameters может быть одним из:
  • Ничем: создаётся текущая дата и время. Например, today = new Date().

  • Строкой, представляющей дату в следующей форме: "Month day, year hours:minutes:seconds".

    Например, Xmas95 = new Date("December 25, 1995 13:30:00").

    Если Вы опустите hours, minutes или seconds, значение будет установлено в 0.

  • Набором целочисленных значений для year, month и day. Например, Xmas95 = new Date(1995,11,25).

    Набором целочисленных значений для year, month, day, hour, minute и seconds. Например, Xmas95 = new Date(1995,11,25,9,30,0).

  • JavaScript 1.2 и предыдущие версии.
    Объект Date работает так:

  • Даты до 1970 не допускаются.

  • JavaScript зависит от платформы, на которой используется; поведение объекта Date варьируется от платформы к платформе.


  • Объект Function

    Объект Function

    Предопределённый объект Function специфицирует строку кода JavaScript, компилируемую как функция.
    Для создания Function-объекта:
    functionObjectName = new Function ([arg1, arg2, ... argn], functionBody)
    functionObjectName это имя переменной или свойства существующего объекта. Это может быть также объект с последующим именем обработчика события в нижнем регистре, например, window.onerror.
    arg1, arg2, ... argn это аргументы, используемые функцией как имена формальных аргументов. Каждое обязано быть строкой, соответствующей верному идентификатору JavaScript; например "x" или "theForm".
    functionBody это строка, специфицирующая код JavaScript, компилируемый как тело функции.
    Function-объекты вычисляются при каждом использовании. Это менее эффективно, чем объявление функции и вызов её в коде, поскольку объявленная функция компилируется.
    Помимо рассмотренного здесь объявления, Вы можете также использовать оператор function. См. книгу Клиентский JavaScript. Справочник.
    Следующий код присваивает функцию переменной setBGColor. Эта функция устанавливает цвет фона текущего документа.
    var setBGColor = new Function("document.bgColor='antiquewhite'")
    Для вызова Function-объекта Вы можете специфицировать имя переменной, как если бы это была функция. Следующий код выполняет функцию, специфицированную переменной setBGColor:
    var colorChoice="antiquewhite"
    if (colorChoice=="antiquewhite") {setBGColor()}
    Вы можете присвоить функцию обработчику события одним из следующих способов:
    1. document.form1.colorButton.onclick=setBGColor2. VALUE="Change background color"
    onClick="setBGColor()">
    Создание переменной setBGColor, показанное выше, похоже на объявление следующей функции:
    function setBGColor() {
    document.bgColor='antiquewhite'
    }
    Вы можете вкладывать функцию в функцию. Вложенная (внутренняя) функция является private для её содержащей (внешней) функции:

  • Внутренняя функция доступна только для операторов внешней функции.

  • Внутренняя функция может использовать аргументы и переменные внешней функции. Внешняя функция не может использовать аргументы и переменные внутренней функции.


  • Объект Math

    Объект Math

    Предопределённый объект Math имеет свойства и методы для математических констант и функций. Например, свойство PI имеет значение pi (3.141...), которое Вы можете использовать в приложениях так:
    Math.PI
    Также и стандартные математические функции являются методами объекта Math. Сюда входят тригонометрические, логарифмические, экспоненциальные и др. функции. Например, если Вы хотите использовать тригонометрическую функцию sine/синус, Вы может записать:
    Math.sin(1.56)
    Учтите, что все тригонометрические методы объекта Math принимают объекты в радианах.
    В таблице дано резюме по методам объекта Math.

    Объект Number

    Объект Number

    Объект Number имеет свойства для числовых констант, таких как максимальное значение, не-число и бесконечность. Вы не можете изменять эти значения и используете их так:
    biggestNum = Number.MAX_VALUE
    smallestNum = Number.MIN_VALUE
    infiniteNum = Number.POSITIVE_INFINITY
    negInfiniteNum = Number.NEGATIVE_INFINITY
    notANum = Number.NaN
    Вы всегда обращаетесь к свойствам предопределённого объекта Number так, как показано выше, а не как к свойствам Number-объекта, созданного Вами.
    В таблице дано резюме по свойствам объекта Number.

    Объект RegExp

    Объект RegExp

    Объект RegExp даёт возможность работать с регулярными выражениями. Он рассмотрен в Главе 4 "Регулярные Выражения".

    Объект String

    Объект 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 в книге
    Клиентский JavaScript. Справочник.
    Объект String также имеет несколько методов для автоматического HTML-форматирования, такие как bold для создания жирного начертания текста и link для создания гиперссылки. Например, Вы можете создать гиперссылку на воображаемый URL методом link:
    mystring.link("http://www.helloworld.com")
    В таблице дано резюме по методам объекта String.

    Объекты и свойства

    Объект в JavaScript имеет ассоциированные с ним свойства. Вы получаете доступ к этим свойствам объектов с помощью простой нотации:
    objectName.propertyName
    И имя объекта, и имя свойства чувствительны к регистру символов. Вы определяете свойство, присваивая ему значение. Например, имеется объект 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

    Обращение к элементам массива

    Обращение к элементам массива

    Вы обращаетесь к элементам массива по порядковому номеру элемента. Например, Вы определили следующий массив:
    myArray = new Array("Wind","Rain","Fire")
    Затем Вы обращаетесь к первому элементу массива myArray[0], а ко второму элементу - myArray[1].
    Индексы массива начинаются от 0, но размер массива (например, myArray.length) отражает реальное количество элементов массива.

    Определение методов

    Определение методов

    Метод это функция, ассоциированная с объектом. Вы определяете метод так же, как и стандартную функцию. Затем Вы используете для ассоциирования функции с существующим объектом следующий синтаксис:
    object.methodname = function_name
    где object это существующий объект, methodname это имя, присвоенное Вами методу, а function_name это имя функции.
    Вы можете затем вызвать метод в контексте объекта:
    object.methodname(params);
    Вы можете определить методы для типа объектов, включив определение метода в функцию-конструктор. Например, Вы могли бы определить функцию форматирования и отображения свойств ранее определённых объектов car; например,
    function displayCar() {
    var result = "A Beautiful " + this.year + " " + this.make
    + " " + this.model
    pretty_print(result)
    }
    где pretty_print это функция для отображения горизонтальной линии и строки. Обратите внимание на использование this для обращения к объекту, которому принадлежит данный метод.
    Вы можете сделать эту функцию методом объектов типа car, добавив оператор
    this.displayCar = displayCar;
    к определению типа объектов. Так, полное определение car теперь будет выглядеть:
    function car(make, model, year, owner) {
    this.make = make
    this.model = model
    this.year = year
    this.owner = owner
    this.displayCar = displayCar
    }
    Затем можно вызвать метод displayCar для каждого объекта:
    car1.displayCar()
    car2.displayCar()
    Это даст вывод показанный на рисунке.

    Определение свойств для типа объектов

    Определение свойств для типа объектов

    Вы можете добавить свойство к ранее определённому типу объектов, используя свойство prototype. Оно определяет свойство, которое используется всеми объектами специфицированного типа, а не только одним экземпляром объекта. Следующий код добавляет свойство color всем объектам типа car и присваивает значение свойства color объекту car1.
    Car.prototype.color=null
    car1.color="black"
    См. свойство prototype объекта Function в книге
    Клиентский JavaScript. Справочник.

    Предопределённые объекты ядра

    В этом разделе рассматриваются предопределённые объекты ядра JavaScript: Array, Boolean, Date, Function, Math, Number, RegExp и String. Предопределённые клиентские объекты рассматриваются в
    Главе 11, "Использование Объектов Navigator'а"
    .

    Создание массива

    Создание массива

    Создание 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"]
    См. также "Литералы Массива".

    Создание новых объектов

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

    Методы объекта Math

    Таблица 7.1 Методы объекта Math


    Метод
    Описание
    absАбсолютное значение
    sin, cos, tanСтандартные тригонометрические функции; аргумент в радианах
    acos, asin, atanИнверсные тригонометрические функции; return-значения в радианах
    exp, logЭкспоненциальный и натуральный логарифмы, база e
    ceilВозвращает наименьшее целое, больше и равное аргументу
    floorВозвращает наибольшее целое, меньше и равное аргументу
    min, maxВозвращается больший или меньший (соответственно) из двух аргументов
    powПоказатель степени; первый аргумент - база, второй - экспонента
    roundОкругляет аргумент до ближайшего целого
    sqrtКвадратный корень

    В отличие от многих других объектов, Вы никогда не создаёте собственные объекты Math. Вы всегда используете предопределённый объект Math.
    Часто бывает удобнее использовать этот объект с оператором with, когда большой участок кода использует математические константы и методы, чтобы не нужно было постоянно печатать "Math". Например,
    with (Math) {
    a = PI * r*r
    y = r*sin(theta)
    x = r*cos(theta)
    }

    Свойства объекта Number

    Таблица 7.2 Свойства объекта Number


    Метод
    Описание
    MAX_VALUEНаибольшее представимое число
    MIN_VALUEНаименьшее представимое число
    NaNСпециальное значение "not a number/не число"
    NEGATIVE_INFINITYСпециальное значение "бесконечность"; возвращается при переполнении
    POSITIVE_INFINITYСпециальное значение "отрицательная бесконечность"; возвращается при переполнении


    Удаление объектов

    Удаление объектов

    Вы можете удалить объект оператором delete. Следующий код показывает, как удалить объект.
    myobj=new Number()
    delete myobj // удаляет объект и возвращает true
    См. также "delete".

    JavaScript 1.1.
    Вы можете удалить объект, установив ссылку на объекта в null (если это последняя ссылка на объект). JavaScript "финализирует" объект немедленно, как часть операции присвоения.
    JavaScript 1.0.
    Вы не можете удалять объекты - они существуют, пока Вы не выйдете со страницы.

    Клиентский JavaScript 1.3 Руководство

    Более гибкие конструкторы

    Показанная функция-конструктор не даёт возможности создавать экземпляры. Как и в Java, Вы можете предоставлять аргументы конструктору для инициализации значений свойств экземпляров. На рисунке показан один из способов сделать это.

    Добавление и удаление свойств

    Добавление и удаление свойств

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

    Добавление свойств

    Добавление свойств

    В JavaScript Вы можете добавить свойства любому объекту на этапе прогона. Вы не ограничены использованием только свойств, предоставленных функцией-конструктором. Для добавления свойств, специфичных для отдельного объекта, Вы присваиваете значение объекту:
    mark.bonus = 3000;
    Теперь объект mark имеет свойство bonus, но другие WorkerBee этого свойства не имеют.
    Если Вы добавляете новое свойство объекту, который используется как функция-конструктор, Вы добавляете это свойство всем объекта, наследующим свойства от данного прототипа. Например, Вы можете добавить свойство specialty ко всем employees следующим оператором:
    Employee.prototype.specialty = "none";
    Как только JavaScript выполнит этот оператор, объект mark также получит свойство specialty со значением "none". На рисунке показан эффект от добавления этого свойства прототипу Employee и последующее переопределение его для прототипа Engineer.

    Глобальная информация в конструкторах

    Глобальная информация в конструкторах

    При создании конструкторов Вы должны быть осторожны, если устанавливаете глобальную информацию в конструкторе. Например, у Вас имеется уникальный идентификатор ID, присваиваемый автоматически каждому новому employee. Вы может использовать такое определение для Employee:
    var idCounter = 1;function Employee (name, dept) {
    this.name = name || "";
    this.dept = dept || "general";
    this.id = idCounter++;
    }
    Теперь, ели Вы создаёте новый Employee, конструктор присваивает ему следующий ID и выполняет инкремент глобального счётчика ID. Поэтому, если Ваш следующий оператор будет таким, как ниже приведённый, victoria.id будет 1, а harry.id будет 2:
    victoria = new Employee("Pigbert, Victoria", "pubs")
    harry = new Employee("Tschopik, Harry", "sales")
    На первый взгляд всё отлично. Однако idCounter увеличивается всякий раз при создании Employee-объекта. Если Вы создаёте всю иерархию Employee, показанную в данной главе, Employee-конструктор вызывается при каждой установке прототипа. Предположим, у Вас имеется такой код:
    var idCounter = 1;function Employee (name, dept) {
    this.name = name || "";
    this.dept = dept || "general";
    this.id = idCounter++;
    }function Manager (name, dept, reports) {...}
    Manager.prototype = new Employee;function WorkerBee (name, dept, projs) {...}
    WorkerBee.prototype = new Employee;function Engineer (name, projs, mach) {...}
    Engineer.prototype = new WorkerBee;function SalesPerson (name, projs, quota) {...}
    SalesPerson.prototype = new WorkerBee;mac = new Engineer("Wood, Mac");
    Предположим далее, что отсутствующие здесь определения имеют свойство base и вызывают конструктор выше себя в цепочке конструкторов. Тогда к моменту создания объекта mac mac.id будет 5.
    В зависимости от приложения может или может не быть важно, увеличивается ли счётчик на это дополнительное количество раз. Если Вам необходимо точное значение счётчика, одним из возможных решений может быть использование следующего конструктора:
    function Employee (name, dept) {
    this.name = name || "";
    this.dept = dept || "general";
    if (name)
    this.id = idCounter++;
    }
    Если Вы создаёте экземпляр Employee для использования его в качестве прототипа, Вы не предоставляете аргументы конструктору. Используя данное определение конструктора и не предоставляя аргументов, конструктор не присваивает значение id и не обновляет счётчик. Следовательно, чтобы Employee получил присвоенный id, Вы обязаны специфицировать имя employee. В данном примере, mac.id может быть 1.

    И снова о наследовании свойств

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

    Языки на базе классов и языки на базе прототипов

    Объектно-ориентированные языки на базе классов, такие как Java и C++, помогут понять две разных сущности: класс и экземпляр.
  • Класс определяет все свойства (методы и поля - в Java, члены, то есть свойства, в C++), характеризующие определённый набор объектов. Класс это абстракция, в отличие от конкретного члена набора объектов, который он описывает. Например, класс Employee может представлять набор всех employees/служащих.

  • Экземпляр, с другой стороны, это инстанциация класса; то есть это один из членов класса. Например, Victoria может быть экземпляром класса Employee, представляя конкретную персону как employee. Экземпляр имеет в точности все свойства своего класса-родителя (ни более, ни менее).

  • В языке на базе прототипов, таком как JavaScript, нет такого отличия: здесь просто имеются объекты. В языке на базе прототипов имеется понятие
    объект-прототип\prototypical object, это объект, используемый как шаблон, по которому получаются начальные свойства объекта. Любой объект может специфицировать свои собственные свойства либо при создании, либо на этапе прогона. Кроме того, любой объект может быть ассоциирован как прототип другого объекта для совместного использования свойств первого объекта.

    Локальные и наследуемые значения

    Локальные и наследуемые значения

    Когда Вы выполняете доступ к свойству объекта, 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".
    Как видно из этих примеров, если Вы хотите иметь значения по умолчанию для свойств объекта и хотите иметь возможность изменять значения по умолчанию на этапе прогона программы, Вы должны устанавливать свойства в прототипе конструктора, а не в самой функции-конструкторе.

    Наследование свойств

    Наследование свойств

    Предположим, Вы создаёте объект mark как WorkerBee, как показано на Рисунке 8.3, следующим оператором:
    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. Некоторые тонкости этого процесса обсуждаются в разделе "И Снова о Наследовании Свойств".
    Поскольку эти конструкторы не предоставляют поддержки значений, специфичных для экземпляра, эта информация является общей/generic. Значения свойств являются значениями по умолчаниями, используемыми всеми новыми объектами, создаваемыми из WorkerBee. Вы можете, конечно, изменить значение любого из этих свойств. Так, Вы можете задать специфическую информацию для mark таким образом:
    mark.name = "Doe, Mark";
    mark.dept = "admin";
    mark.projects = ["navigator"];

    Определение класса

    Определение класса

    В языках на базе классов Вы определяете класс в отдельном определении класса\class definition. Здесь Вы можете специфицировать специальные методы, называемые конструкторами, которые создают экземпляры данного класса. Метод-конструктор может специфицировать начальные значения свойств экземпляров и выполнять иную работу, необходимую на этапе создания экземпляров. Вы используете операцию new вместе с методом-конструктором для создания экземпляров класса.
    В JavaScript используется похожая модель, но отсутствует определение класса, отдельное от конструктора. Вместо этого Вы определяете функцию-конструктор для создания объектов с определённым набором начальных значений и свойств. Любая функция JavaScript может использоваться как конструктор. Вы используете операцию new вместе с функцией-конструктором для создания нового объекта.

    Определение взаимоотношений экземпляров

    Определение взаимоотношений экземпляров

    Возможно, Вы захотите узнать, какие объекты находятся в цепочке прототипов данного объекта, чтобы определить, из какого объекта данный объект наследует свойства. В языках на базе классов Вы можете использовать для этого операцию instanceof. В JavaScript нет instanceof, но Вы сами можете написать такую функцию.
    Как сказано в "Наследовании Свойств", если Вы используете операцию new с функцией-конструктором для создания новых объектов, JavaScript устанавливает в свойство __proto__ нового объекта значение свойства prototype функции-конструктора. Вы можете использовать это для проверки цепочки прототипов.
    Например, у Вас есть уже показанный ранее набор определений с соответственно установленными прототипами. Создайте объект __proto__ так:
    chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
    С эти объектом все следующие операторы true:
    chris.__proto__ == Engineer.prototype;
    chris.__proto__.__proto__ == WorkerBee.prototype;
    chris.__proto__.__proto__.__proto__ == Employee.prototype;
    chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
    chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
    Имея это, Вы можете написать функцию instanceOf:
    function instanceOf(object, constructor) {
    while (object != null) {
    if (object == constructor.prototype)
    return true;
    object = object.__proto__;
    }
    return false;
    }
    При таком определении все следующие выражения true:
    instanceOf (chris, Engineer)
    instanceOf (chris, WorkerBee)
    instanceOf (chris, Employee)
    instanceOf (chris, Object)
    Но следующее выражение будет false:
    instanceOf (chris, SalesPerson)

    Отличия. Резюме.

    Отличия. Резюме.

    В таблице дано краткое резюме по некоторым отличительным особенностям языков. Остальная часть данной главы посвящена деталям использования конструкторов и прототипов языка JavaScript для создания иерархии и делаются сравнения с аналогичными действиями в Java.

    Подклассы и наследование

    Подклассы и наследование

    В языках на основе классов Вы создаёте иерархию классов через определения классов. В определении класса Вы можете специфицировать, что новый класс является подклассом\subclass уже существующего класса. Подкласс наследует все свойства своего родителя (суперкласса) и может добавлять новые свойства или изменять наследуемые. Например, класс Employee имеет только свойства name и dept, а Manager является подклассом класса Employee и добавляет свойство reports. В этом случае экземпляры класса Manager будут иметь три свойства: name, dept и reports.
    В JavaScript реализовано наследование, что даёт возможность ассоциировать объект-прототип с любой функцией-конструктором. Так, Вы можете воспроизвести тот же пример Employee-Manager, но используя несколько иную терминологию. Сначала Вы определяете функцию-конструктор Employee, специфицируя свойства name и dept. Затем Вы определяете функцию-конструктор Manager, специфицируя свойство reports. Наконец, Вы присваиваете новый объект Employee как prototype функции-конструктору Manager. Затем создаёте новый объект Manager, который наследует свойства name и dept из объекта Employee.

    Пример Employee

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

    Простая иерархия объектов

    Рисунок 8.1 Простая иерархия объектов

    Простая иерархия объектов
    В этом примере используются следующие объекты:

  • Employee имеет свойства name (значение по умолчанию - пустая строка) и dept (значение по умолчанию - "general").

  • Manager базируется на Employee. Он добавляет свойство reports (значение по умолчанию - пустой массив, предназначенный для хранения массива Employee-объектов как значений).

  • WorkerBee также основан на Employee. Он добавляет свойство projects (значение по умолчанию - пустой массив, предназначенный для хранения массива строк как значений).

  • SalesPerson базируется на WorkerBee. Он добавляет свойство quota (значение по умолчанию - 100). Также переопределяет свойство dept значением "sales", указывая, что все менеджеры по продажам/salespersons находятся в этом отделе.

  • Engineer базируется на WorkerBee. Он добавляет свойство machine (значение по умолчанию - пустая строка), а также переопределяет свойство dept property значением "engineering".


  • Определения объекта Employee

    Рисунок 8.2 Определения объекта Employee

    Определения объекта Employee
    Следующие определения Employee в Java и в JavaScript похожи. Единственное отличие - Вы должны специфицировать тип каждого свойства в Java, но не в JavaScript, и Вы должны создать конкретный метод-конструктор для Java-класса.
    JavaScript
    Java
    function Employee () {
    this.name = "";
    this.dept = "general";

    }
    public class Employee {
    public String name;

    public String dept;
    public Employee () {

    this.name = "";

    this.dept = "general";
    }
    }

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

    JavaScript
    Java
    function Manager () {
    this.reports = [];
    }
    Manager.prototype = new Employee;function WorkerBee () {
    this.projects = [];
    }
    WorkerBee.prototype = new Employee;
    public class Manager extends Employee {
    public Employee[] reports;
    public Manager () {
    this.reports = new Employee[0];
    }
    }public class WorkerBee extends Employee {
    public String[] projects;
    public WorkerBee () {
    this.projects = new String[0];
    }
    }

    Определения Engineer и SalesPerson создают объекты, которые являются потомками WorkerBee и, следовательно, потомками Employee. Объект этих типов имеет свойства всех объектов, стоящих выше него в цепочке иерархии. Кроме того, эти определения переопределяют наследуемое значение свойства dept новыми значениями, специфичными для этих объектов.

    JavaScript

    Java
    function SalesPerson () {
    this.dept = "sales";
    this.quota = 100;
    }
    SalesPerson.prototype = new WorkerBee;function Engineer () {
    this.dept = "engineering";
    this.machine = "";
    }
    Engineer.prototype = new WorkerBee;
    public class SalesPerson extends WorkerBee {
    public double quota;
    public SalesPerson () {
    this.dept = "sales";
    this.quota = 100.0;
    }
    }public class Engineer extends WorkerBee {
    public String machine;
    public Engineer () {
    this.dept = "engineering";
    this.machine = "";
    }
    }
    Используя эти определения, Вы можете создавать экземпляры этих объектов, которые получают значения по умолчанию своих свойств. Рисунок 8.3 иллюстрирует использование этих определений JavaScript для создания новых объектов и показывает значения свойств новых объектов.

    ПРИМЕЧАНИЕ:

    Термин экземпляр\instance имеет специфическое техническое значение в языках программирования на базе классов. В них экземпляр это отдельный член класса, фундаментально отличающийся от класса. В JavaScript "экземпляр/instance" не имеет этого технического значения, поскольку JavaScript не различает классы и экземпляры. Однако, говоря о JavaScript, "экземпляр" может использоваться неформально для обозначения объекта, созданного с использованием конкретной функции-конструктора. Так, в данном примере, Вы можете неформально сказать, что jane это Engineer-экземпляр. Аналогично, хотя термины parent\родитель, child\дочерний, ancestor\предок и descendant\потомок не имеют формальных значений в JavaScript, Вы можете использовать их неформально для обращения к объектам выше или ниже по цепочке прототипов.

    Создание объектов с помощью простых определений

    Рисунок 8.3 Создание объектов с помощью простых определений

    Создание объектов с помощью простых определений

    В таблице показаны определения Java

    Рисунок 8.5 Специфицирование свойств в конструкторе, этап 1

    В таблице показаны определения Java

    В таблице показаны определения Java и JavaScript для этих объектов.

    JavaScript

    Java
    function Employee (name, dept) {
    this.name = name || "";
    this.dept = dept || "general";
    }
    public class Employee {
    public String name;
    public String dept;
    public Employee () {
    this("", "general");
    }
    public Employee (name) {
    this(name, "general");
    }
    public Employee (name, dept) {
    this.name = name;
    this.dept = dept;
    }
    }
    function WorkerBee (projs) {
    this.projects = projs || [];
    }
    WorkerBee.prototype = new Employee;
    public class WorkerBee extends Employee {
    public String[] projects;
    public WorkerBee () {
    this(new String[0]);
    }
    public WorkerBee (String[] projs) {
    this.projects = projs;
    }
    }
    function Engineer (mach) {
    this.dept = "engineering";
    this.machine = mach || "";
    }
    Engineer.prototype = new WorkerBee;
    public class Engineer extends WorkerBee {
    public String machine;
    public WorkerBee () {
    this.dept = "engineering";
    this.machine = "";
    }
    public WorkerBee (mach) {
    this.dept = "engineering";
    this.machine = mach;
    }
    }
    Эти определения JavaScript используют специальную идиому для установки значений по умолчанию:


    this.name = name || "";

    Логическая операция ИЛИ (||) в JavaScript вычисляет первый аргумент. Если он конвертируется в true, операция возвращает его. Иначе операция возвращает значение второго аргумента. Следовательно, эта строка кода проверяет, имеет ли name подходящее значение для свойства name. Если имеет, это значение устанавливается в this.name. Иначе - в this.name устанавливается пустая строка. Эта идиома используется в данной главе для краткости; однако она может, на первый взгляд, показаться непонятной.

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

    jane = new Engineer("belau");

    Jane-свойства будут теперь:

    jane.name == "";
    jane.dept == "general";
    jane.projects == [];
    jane.machine == "belau"

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

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

    Рассмотрим одно из этих определений

    Рисунок 8.6 Специфицирование свойств в конструкторе, этап 2

    Рассмотрим одно из этих определений

    Рассмотрим одно из этих определений детально. Вот новое определение для конструктора Engineer:

    function Engineer (name, projs, mach) {
    this.base = WorkerBee;
    this.base(name, "engineering", projs);
    this.machine = mach || "";
    }

    Предположим, Вы создаёте новый Engineer-объект:

    jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");

    JavaScript выполняет следующее:



  • Операция new создаёт общий объект и присваивает его свойство __proto__ Engineer.prototype.


  • Операция new передаёт этот новый объект Engineer-конструктору как значение ключевого слова this.


  • Конструктор создаёт новое свойство base для этого объекта и присваивает значение конструктора WorkerBee свойству base. Это делает конструктор WorkerBee методом Engineer-объекта.


  • Имя свойства base не является специальным. Вы может использовать любое верное имя свойства; base просто подходит по смыслу.

    Конструктор вызывает метод base, передавая ему в качестве аргументов два аргумента из переданных конструктору ("Doe, Jane" и ["navigator", "javascript"]), а также строку "engineering". Явное использование "engineering" в конструкторе указывает, что все Engineer-объекты имеют одно значение для наследуемого свойства dept, и что это значение переопределяет значение, наследуемое из Employee.


  • Поскольку base это метод из Engineer, внутри вызова base JavaScript связывает ключевое слово this с объектом, созданным на Этапе 1. Таким образом, функция WorkerBee в свою очередь передаёт аргументы "Doe, Jane" и ["navigator", "javascript"] в функцию-конструктор Employee. После возвращения из функции-конструктора Employee, функция WorkerBee использует оставшийся аргумент для установки свойства projects.


  • После возвращения из метода base, конструктор Engineer инициализирует свойство machine объекта значением "belau".



  • После возвращения из конструктора, JavaScript присваивает новый объект переменной jane.


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

    function Engineer (name, projs, mach) {
    this.base = WorkerBee;
    this.base(name, "engineering", projs);
    this.machine = mach || "";
    }
    jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
    Employee.prototype.specialty = "none";

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

    function Engineer (name, projs, mach) {
    this.base = WorkerBee;
    this.base(name, "engineering", projs);
    this.machine = mach || "";
    }
    Engineer.prototype = new WorkerBee;
    jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
    Employee.prototype.specialty = "none";

    Теперь значение свойства specialty объекта jane равно "none".

    Создание иерархии

    Есть несколько способов создания функции-конструктора для реализации иерархии Employee. Выбор конкретного способа во многом зависит от того, что должно будет делать Ваше приложение.
    В данном разделе показано, как использовать очень простое (и сравнительно негибкое) определение для демонстрации создания работающей иерархии. В этих определениях Вы не можете специфицировать значения свойств, когда создаёте объект. Вновь создаваемый объект просто получает все значения по умолчанию, которые Вы можете изменить позднее. Рисунок 8.2 показывает иерархию с несколькими простыми определениями.
    В реальном приложении, Вы, вероятно, определите конструктор, который позволит задавать начальные значения свойств на этапе создания объекта (см. "Более Гибкие Конструкторы"). Итак, эти простые определения демонстрируют появление иерархии.

    Свойства объекта

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

    Сравнение объектных

    Таблица 8.1 Сравнение объектных систем языков на базе классов (Java)
    и языков на базе прототипов (JavaScript)

    На базе классов (Java)
    На базе прототипов (JavaScript)
    Класс и экземпляр это разные сущности.Все объекты являются экземплярами.
    Класс определяется в определении класса; инстанциация (создание экземпляров) производится методами-конструкторами.Набор объектов создаётся и определяется функциями-конструкторами.
    Одиночный объект создаётся операцией new.То же самое.
    Иерархия объектов создаётся через использование определения класса для определения подклассов существующих классов.Иерархия объектов создаётся путём присвоения объекта как прототипа, ассоциированного с функцией-конструктором.
    Свойства наследуются по цепочке классов.Свойства наследуются по цепочке прототипов.
    Определение класса специфицирует все свойства всех экземпляров данного класса. Свойства нельзя добавлять динамически на этапе прогона.Функция-конструктор или прототип специфицируют начальный набор свойств. Свойства могут добавляться динамически отдельному объекту или целому набору объектов.


    Клиентский JavaScript 1.3 Руководство

    Использование кавычек

    Везде, где Вы указываете строку в кавычках внутри строкового литерала, используйте одинарные кавычки (') для ограничения строкового литерала. Это даст скрипту возможность отличить литерал внутри строки. В следующем примере функция bar содержит литерал "left" в значении атрибута, заключённого в двойные кавычки:
    function bar(widthPct) {
    document.write("
    ")
    }
    Вот другой пример:


    Использование тэга SCRIPT

    Тэг
    В документе может быть несколько тэгов


    ...


    Показано использование двух разных версий

    Показано использование двух разных версий документа JavaScript, одна - для JavaScript 1.1, а вторая - для JavaScript 1.2. По умолчанию загружается документ для JavaScript 1.1. Если у пользователя запущен Navigator 4.0, метод replace заменяет страницу.

    [1.1-совместимая страница продолжается здесь...]

    здесь нужно проверить версию jsVersion

    Показано, как тестировать свойство navigator.userAgent для определения версии Navigator'а 4.0. Затем код выполняет версии 1.1 и 1.2.

    [ здесь нужно проверить версию jsVersion перед использованием расширения 1.1 или 1.2]

    первый скрипт

    Пример: первый скрипт

    На Рисунке 9.1 показан простой скрипт, выводящий в Navigator'е:
    Hello, net!
    That's all, folks.
    Заметьте, что здесь нет отличий в отображении первой строки, генерируемой JavaScript, и второй строки, генерируемой обычным HTML.

    Простой скрипт

    Рисунок 9.1 Простой скрипт


    Простой скрипт

    Вы иногда видите точку с запятой в конце каждой строки JavaScript. Вообще-то символ ; не обязателен и необходим только тогда, когда в одной строке вводятся несколько операторов. Это чаще всего бывает в обработчиках событий, которые обсуждаются в Главе 10, "Обработка Событий".

    Результат использования мнемоники JavaScript

    Рисунок 9.2 Результат использования мнемоники JavaScript


    Результат использования мнемоники JavaScript

    Как и в HTML, после отображения вывода вид страницы может измениться только при её перезагрузке.
    В отличие от обычных мнемоник, которые могут появляться в любом месте текстового потока HTML, мнемоники JavaScript интерпретируются только в правой части пары имя/значение HTML-атрибутов. Например, если у Вас имеется оператор:

    &{myTitle};


    он выведет строку myTitle вместо значения переменной myTitle.

    Скрытие скриптов в тэгах комментария

    Скрытие скриптов в тэгах комментария

    Только версии Navigator'а 2.0 и более поздние распознают JavaScript. Чтобы другие браузеры игнорировали код JavaScript, поместите весь текст скрипта внутри тэгов комментария HTML и вставьте перед конечным тэгом комментария двойной слэш (//), являющийся символом однострочного комментария JavaScript:

    Поскольку браузеры обычно игнорируют неизвестные тэги, браузеры, не работающие с JavaScript, будут игнорировать начальный и конечный тэги SCRIPT. Все операторы скрипта находятся внутри тэгов HTML-комментария, поэтому они также игнорируются. Navigator правильно интерпретирует тэги SCRIPT и игнорирует строку скрипта, начинающуюся с двойного слэша (//).
    Хотя Вы не обязаны использовать эту технику, это рекомендуется делать, чтобы Ваши страницы не генерировали неотформатированные операторы скрипта у пользователей, не использующих Navigator 2.0 и более поздние его версии.
    ПРИМЕЧАНИЕ: Для упрощения, некоторые примеры в этой книге не прячут скрипты.

    Специфицирование файла с кодом JavaScript

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


    использование обработчика события

    Пример: использование обработчика события

    В форме, показанной на следующем рисунке, Вы можете ввести выражение (например, 2+2) в первое текстовое поле, а затем щёлкнуть кнопку. Во втором поле будет выведено значение выражения (в данном случае, 4).

    Пример проверяющих функций

    Пример проверяющих функций

    Вот примеры простых проверяющих функций:



    isaPosNum это простая функция, которая возвращает true, если её аргумент - положительное число, и false - в ином случае.
    qty_check принимает три аргумента: объект, соответствующий проверяемому элементу формы (item), и минимальное и максимальное допустимые значения для item (min и max). Она проверяет, является ли item числом в диапазоне от min до max, и выводит диалог alert, если это не так.
    validateAndSubmit принимает в качестве аргумента Form-объект; она использует qty_check для проверки значения элемента формы и отправляет форму, если ввод верен. В ином случае она выводит окно alert и не отправляет форму.

    Проверка данных, введённых в форму

    Важным является использование JavaScript для проверки введённых в форму данных, предназначенных для последующей обработки серверными программами, такими как приложения серверного JavaScript или CGI-программы. Эта проверка делается по следующими причинам:
  • Уменьшается нагрузка на сервер. "Плохие" данные фильтруются уже перед отправкой данных на сервер.

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

  • В общем, Вам понадобится проверять ввод как минимум в двух случаях:

  • После ввода данных пользователем - обработчиком onChange в каждом элементе формы, который Вам нужно проверить.

  • Если пользователь отправляет форму - обработчиком onClick submits-кнопки, отправляющей форму.

  • Страница JavaScript на сайте DevEdge содержит ссылки на примеры кода. Одна из этих ссылок - это полный набор функций для проверки данных формы.
    В следующем разделе даны некоторые простые примеры, но посмотрите также примеры на сайте DevEdge.

    Регистрация обработчика события

    Регистрация обработчика события

    Наконец, функция регистрируется как обработчик данного события в окне:
    window.onClick = clickHandler;

    Форма с обработчиком события

    Рисунок 10.1 Форма с обработчиком события


    Форма с обработчиком события

    Скрипт для этой формы таков:




    Enter an expression:



    Result:



    HEAD/шапка документа определяет функцию compute, принимающую один аргумент, f, который является Form-объектом. Эта функция использует метод window.confirm для отображения диалога Confirm с кнопками OK и Cancel.
    Если пользователь щёлкает OK, confirm возвращает true, а значением текстового поля result становится значение eval(f.expr.value). Функция JavaScript eval вычисляет свой аргумент, который может быть любой строкой, представляющей любые выражение или операторы JavaScript.
    Если пользователь нажал Cancel, confirm возвращает false, и метод alert выводит другое сообщение.
    На форме имеется кнопка с обработчиком onClick, в котором вызывается функция compute. Когда пользователь щёлкает кнопку, JavaScript вызывает compute с аргументом this.form, который означает текущий Form-объект. В compute на this.form делается ссылка как на аргумент f.

    Обработчики Событий JavaScript

    Таблица 10.1 Обработчики Событий JavaScript

    Событие
    Применяется кВозникает, когда
    Обработчик
    Abortизображениямпользователь прерывает загрузку изображения (например, щёлкну гиперссылку или кнопку Stop)onAbort
    Blurокнам и всем элементам формыпользователь убирает фокус ввода с окна или элемента формыonBlur
    Changeтекстовым полям, спискам selectпользователь изменяет значение элементаonChange
    Clickкнопкам, radio-кнопкам, переключателям/checkboxes, кнопкам submit и reset, гиперссылкампользователь щёлкает по элементу формы или кнопкеonClick
    DragDropокнампользователь "отпускает" мышью объект в окне браузера, как при перемещении файловonDragDrop
    Errorизображениям, окнамзагрузка документа или изображения вызвала ошибкуonError
    Focusокнам и всем элементам формыпользователь передаёт фокус окну или элементу формыonFocus
    KeyDownдокументам, изображениям, гиперссылкам, текстовым полямпользователь нажал клавишу клавиатурыonKeyDown
    KeyPressдокументам, изображениям, гиперссылкам, текстовым полямпользователь нажал или (?) удерживает нажатой клавишу клавиатурыonKeyPress
    KeyUpдокументам, изображениям, гиперссылкам, текстовым полямпользователь отпустил клавишу клавиатурыonKeyUp
    Loadтелу документапользователь загружает страницу в NavigatoronLoad
    MouseDownдокументам, кнопкам, гиперссылкампользователь нажал клавишу мышиonMouseDown
    MouseMoveпо умолчанию - ни к чемупользователь перемещает курсорonMouseMove
    MouseOutобластям, гиперссылкампользователь перемещает курсор за пределы клиентской карты изображений или гиперссылкиonMouseOut
    MouseOverгиперссылкампользователь перемещает курсор над гиперссылкойonMouseOver
    MouseUpдокументам, кнопкам, гиперссылкампользователь отпускает клавишу мышиonMouseUp
    Moveокнампользователь или скрипт перемещает окноonMove
    Resetформампользователь восстанавливает начальные значения формы (щёлкает кнопку Reset)onReset
    Resizeокнампользователь или скрипт изменяет размер окнаonResize
    Selectтекстовым полямпользователь выделяет поле ввода элемента формыonSelect
    Submitформампользователь отправляет формуonSubmit
    Unloadтелу документапользователь покидает страницуonUnload


    Включение захвата событий

    Включение захвата событий

    Для настройки захвата окном всех событий Click используйте примерно такой оператор:
    window.captureEvents(Event.CLICK);
    Аргументом свойства captureEvents объекта event является тип захватываемого события. Для захвата нескольких типов событий, аргументом является список с разделением символом (|). Например, следующий оператор захватывает события Click, MouseDown и MouseUp:
    window.captureEvents(Event.CLICK | Event.MOUSEDOWN | Event.MOUSEUP)
    ПРИМЕЧАНИЕ:
    Если окно с фрэймами должно захватывать события на страницах, загружаемых с различных серверов, Вам необходимо использовать captureEvents в маркированном скрипте и вызывать enableExternalCapture. О маркированных скриптах см. Главу 14 "Безопасность в JavaScript".

    Вызов обработчиков событий явным образом

    Вызов обработчиков событий явным образом

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

  • onClick="fun1()">

    JavaScript 1.0. Вы не можете устанавливать обработчик события.
  • Обработчики событий являются ссылками на функции, поэтому Вы обязаны присвоить fun2 самой себе, а не fun2() (второй вариант вызывает fun2 и содержит любые тип и значение, возвращаемые функцией fun2).

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


  • JavaScript 1.1 и предыдущие версии.

    Вы обязаны вводить имена обработчиков символами нижнего регистра, например, myForm.onsubmit или myButton.onclick.

    Захват событий

    Обычно событие обрабатывается объектом, в котором это событие возникает. Например, если пользователь щёлкает по кнопке, вызывается обработчик этого события. Иногда Вам может понадобиться, чтобы объект window или document обрабатывал определённые события. Например, Вам может понадобиться, чтобы объект document обрабатывал все события MouseDown вне зависимости от того, в каком месте документа они возникают.
    Модель захвата событий JavaScript даёт возможность определять методы, которые захватывают и обрабатывают события, до того как они достигнут своей предполагаемой цели. Для этого объекты window, document и layer используют следующие методы:
  • captureEvents - захватывает события специфицированного типа.

  • releaseEvents - игнорирует захват событий специфицированного типа.

  • routeEvent - перенаправляет захваченное событие специфицированному объекту.

  • handleEvent - обрабатывает захваченное событие (это не метод объекта layer).


  • JavaScript1.1 и предыдущие версии.
    Захват событий невозможен.
    Как пример, предположим, Вы хотите захватить все события Click, возникающие в окне. В сжатом виде, шаги по захвату событий таковы:

  • Включить захват событий

  • Определить обработчик события

  • Зарегистрировать обработчик события

  • В последующих разделах эти шаги поясняются.

    Клиентский JavaScript 1.3 Руководство

    Иерархия объектов Navigator'а

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

    Использование метода write

    Метод write объекта document отображает вывод в Navigator'е. "Зачем?", спросите Вы, "ведь это уже делает HTML". Но в скрипте можно сделать то, чего не может обычный HTML. Например, Вы можете вывести текст на основе выполнения условия или аргументов переменной. Поэтому write это один из наиболее часто используемых методов JavaScript.
    Метод write принимает любое количество строковых аргументов, которые могут быть строковыми литералами или переменными. Вы можете также использовать операцию конкатенации строк (+) для создания одной строки из нескольких при помощи оператора write.
    Вот скрипт, генерирующий динамический HTML с помощью JavaScript:




    This is some standard HTML, unlike the above that is generated.

    В HEAD этого документа определены две функции:

  • bar, которая отображает горизонтальную линию HTML, имеющую ширину, специфицированную аргументом функции.

  • output, которая отображает заголовок HTML того уровня, который специфицирован первым аргументом, и текст параграфа, специфицированный третьим аргументом.

  • Затем в тэге BODY документа эти две функции вызываются и дают на выходе:

    Ключевые объекты Navigator'а

    В этом разделе рассмотрены некоторые наиболее используемые объекты Navigator'а: window, Frame, document, Form, location, history и navigator. Дополнительно об этих объектах см. книгу
    Клиентский JavaScript.
    Справочник.

    Массивы объектов Navigator'а

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

    Объект document

    Объект document

    Каждая страница имеет единственный объект document.
    Поскольку его методы write и writeln генерируют HTML, объект document является одним из наиболее используемых объектов Navigator'а. О методах write и writeln см. раздел "Использование Метода write".
    Объект document имеет несколько свойств, отражающих цвет фона, текста и гиперссылок страницы: bgColor, fgColor, linkColor, alinkColor и vlinkColor. Часто используются lastModified, дата последнего изменения страницы, referrer, предыдущий URL, посещённый клиентом, и URL, URL документа. Свойство cookie даёт возможность устанавливать и получать значения кук; см. также "Использование Кук".
    Объект document является предком всех объектов Anchor, Applet, Area, Form, Image, Layer, Link и Plugin страницы.
    Пользователи могут печатать и сохранять сгенерированный HTML, используя команды меню File Navigator'а (JavaScript1.1 и позднее).

    Объект Form

    Объект Form

    Каждая форма документа создаёт объект Form. Поскольку в документе может быть не одна форма, Form-объекты хранятся в массиве forms. Первая форма (самая верхняя на странице) это forms[0], вторая - forms[1], и так далее. Помимо обращения к форме по имени, Вы можете обратиться к первой (например) форме так:
    document.forms[0]
    Другие элементы формы, такие как текстовые поля, радио-кнопки и т.д., хранятся в массиве elements. Вы можете обратиться к первому элементу (независимо от его вида) первой формы так:
    document.forms[0].elements[0]
    Каждый элемент формы имеет свойство form, которое является ссылкой на родительскую форму элемента. Это свойство используется в основном в обработчиках событий, где может понадобиться обратиться к другому элементу на текущей форме. В следующем примере форма myForm содержит Text-объект и кнопку. Если пользователь щёлкает по кнопке, значением Text-объекта становится имя формы. Обработчик onClick кнопки использует this.form для обращения к родительской форме, myForm.

    Form name:

    onClick="this.form.text1.value=this.form.name">


    Объект history

    Объект history

    Объект history содержит список строк, представляющих URL'ы, посещённые клиентом. Вы можете получить текущее, предыдущее и следующее вхождение из history через использование свойств current, next и previous объекта history. Вы получить доступ к другим значениям в history, используя массив history. Этот массив содержит вхождение для каждого вхождения history в порядке исходного кода; каждое вхождение массива это строка, содержащая URL.
    Можно также перенаправить клиент к любому вхождению списка history методом go. Например, следующий код загружает URL, находящийся на две позиции назад в списке history клиента.
    history.go(-2)
    Следующий код перезагружает текущую страницу:
    history.go(0)
    Список history отображается в меню Go Navigator'а.

    Объект location

    Объект location

    Объект location имеет свойства на основе текущего URL. Например, свойство hostname это сервер и имя домена сервера - хоста текущего документа.
    Объект location имеет два метода:

  • reload - форсирует перезагрузку текущего документа окна.

  • replace - загружает специфицированный URL поверх текущего вхождения списка history.


  • Объект navigator

    Объект navigator

    Объект navigator содержит информацию о версии используемого Navigator'а. Например, свойство appName специфицирует имя браузера, а свойство appVersion специфицирует версию Navigator'а.
    Объект navigator имеет три метода:
  • javaEnabled специфицирует, включен ли Java

  • preference позволяет использовать маркированный скрипт для получения различных пользовательских настроек (JavaScript1.2 и позднее)

  • taintEnabled специфицирует, включено ли разрушение данных/tainting (только JavaScript 1.1)


  • Объекты window и Frame

    Объекты window и Frame

    Объект window является "родительским" объектом для всех объектов в Navigator'е. Вы можете создать несколько окон в приложении JavaScript. Объект Frame определяется тэгом FRAME в документе FRAMESET. Frame-объекты имеют те же свойства и методы, что и объекты window, и отличаются только способом отображения.
    Объект window имеет несколько широко используемых методов, в том числе:

  • open и close: открывают и закрывают окно браузера; Вы можете специфицировать размер окна, его содержимое и наличие панели кнопок/button bar, адресной строки/location field и других "chrome"-атрибутов.

  • alert - Выводит диалоговое окно Alert с сообщением.

  • confirm - Выводит диалоговое окно Confirm с кнопками OK и Cancel.

  • prompt - Выводит диалоговое окно Prompt с текстовым полем для ввода значения.
  • blur и focus - Убирают и передают фокус окну.

  • scrollTo - Прокручивает окно на специфицированные координаты.

  • setInterval - Вычисляет выражение или вызывает функцию многократно по истечении специфицированного периода времени.

  • setTimeout - Вычисляет выражение или вызывает функцию однократно по истечении специфицированного периода времени.

  • window имеет также несколько свойств, которые могут устанавливаются Вами, таких как location и status.
    Вы можете установить location для перехода клиента к другому URL. Например, следующий оператор перенаправляет клиент на домашнюю страницу Netscape, как если бы пользователь щёлкнул по гиперссылке или как-нибудь иначе загрузил URL:
    location = "http://home.netscape.com"
    Свойство status можно использовать для показа сообщения в статусной строке/status bar внизу клиентского окна; дополнительно см. "Использование Статусной Строки".
    Об окнах и фрэймах см. дополнительно Главу 12 "Использование Окон и Фрэймов". В данной книге не рассматривается полный набор методов и свойств объекта window. Полный список см. в книге
    Клиентский JavaScript.
    Справочник.

    Отражение JavaScript и вывод HTML

    В JavaScript значения свойств объекта основаны на содержимом Вашего HTML-документа, что иногда называется reflection/отражением, поскольку значения свойств отражают HTML. Для понимания отражения JavaScript важно разобраться, как Navigator выполняет layout\вывод - процесс трансформации Navigator'ом HTML-тэгов в графическое отображение на экране Вашего компьютера.
    Обычно отображение выполняется в Navigator'е последовательно: Navigator стартует от верха HTML-файла и проходит до конца документа (вниз), отображая вывод на экране по мере прохождения документа. Из-за такого выполнения "сверху вниз", JavaScript отражает только HTML, который обнаружен. Например, Вы определяете форму и два элемента для ввода текста:



    Эти элементы формы отражаются как объекты JavaScript, которые могут использоваться Вами после определения формы: document.statform.userName и document.statform.Age. Например, Вы можете отобразить значения этих объектов в скрипте после определения формы:

    Однако, если Вы попытаетесь сделать это до того как форма определена, (выше определения формы на HTML-странице), Вы можете получить ошибку, поскольку объект пока ещё не существует в Navigator'е.
    Аналогично, если вывод состоялся, установка значения свойства не влияет на значение или вид документа. Например, Вы определили заголовок документа:
    My JavaScript Page
    Он отражается в JavaScript как значение свойства document.title. После того как Navigator отобразил этот заголовок в строке заголовка окна Navigator'а, Вы не можете изменить это значение в JavaScript. Если у Вас имеется такой скрипт далее на странице, он не изменит значение document.title, не повлияет на вид страницы или вызовет генерацию ошибки.
    document.title = "The New Improved JavaScript Page"
    Из этого правила есть несколько важных исключений: Вы можете динамически обновлять значения элементов. Например, следующий скрипт определяет текстовое поле, которое первоначально выводит строку "Starting Value." При каждом щелчке по кнопке Вы добавляете текст "...Updated!" к этому значению.


    onClick="document.demoForm.mytext.value += '...Updated!' ">

    Это простой пример обновления элемента формы после завершения вывода документа.
    Используя обработчики событий, Вы можете также изменять некоторые другие свойства после завершения вывода документа, такие как document.bgColor.

    Печать вывода

    Печать вывода

    Navigator версии 3.0 печатает вывод, созданный в JavaScript. Для распечатки вывода, пользователь выбирает Print из меню File Navigator'а. Navigator2.0 не распечатывает вывод, создаваемый JavaScript.
    Если Вы распечатываете страницу, содержащую слои/layers (Navigator 4.0 и позднее), каждый слой печатается отдельно на той же странице. Например, если три слоя перекрывают друг друга в браузере, распечатанная страница показывает каждый слой отдельно.
    Если Вы выбрали Page Source из меню View Navigator'а или View Frame Source из контекстного меню (правой клавишей мыши), web-браузер отображает содержимое HTML-файла со сгенерированным HTML. Если Вы хотите просмотреть исходный HTML со скриптами генерирующими HTML (с методами document.write и document.writeln), не используйте меню Page Source и View Frame Source. Тогда используйте протокол view-source:. Например, предположим, файл file://c|/test.html содержит такой текст:


    Hello,



    При загрузке этого URL браузер выведет:
    Hello, there.
    Если выбрать Page Source из меню View, браузер выведет:


    Hello,
    there.


    Если загрузить view-source:file://c|/test.html, браузер выведет:


    Hello,




    Иерархия объектов Navigator'а

    Рисунок 11.1 Иерархия объектов Navigator'а

    Иерархия объектов Navigator'а
    В данной иерархии "потомки" объектов являются их свойствами. Например, форма form1 является объектом, а также свойством объекта document, и к ней обращаются document.form1.
    Список всех объектов, их свойств, методов и обработчиков событий см. в книге
    Клиентский JavaScript.
    Справочник.
    На каждой странице имеются следующие объекты:

  • navigator: имеет свойства - имя и версию используемого Navigator'а, MIME-типы, поддерживаемые клиентом и plug-in'ы, установленные на клиенте.

  • window: объект верхнего уровня/top-level; имеет свойства, которые применяются ко всему окну. Каждое "дочернее окно" в документе с фрэймами также является window-объектом.

  • document: имеет свойства на основе содержимого документа, такого как заголовок, цвет фона, гиперссылки и формы.

  • location: имеет свойства на основе текущего URL.

  • history: имеет свойства, представляющие URL'ы, которые клиент запрашивал ранее.

  • В зависимости от содержимого, документ может содержать и другие объекты. Например, каждая форма (определённая тэгом FORM) в документе имеет соответствующий объект Form.
    Для обращения к конкретным свойствам Вы обязаны специфицировать имена объекта и всех его предков. Обычно объект получает имя в атрибуте NAME соответствующего HTML-тэга. Дополнительную информацию и пример см. в
    Главе 12 "Использование Окон и Фрэймов"
    .
    Например, следующий код обращается к свойству value текстового поля text1 на форме myform в текущем документе:
    document.myform.text1.value
    Если объект находится на форме, Вы обязаны включать имя формы при обращении к этому объекту, даже если объект не обязан быть на форме. Например, изображения не обязаны находиться на форме. Следующий код обращается к изображению, находящемуся на форме:
    document.imageForm.aircraft.src='f15e.gif'
    Следующий код обращается к изображению, которое не находится на форме:
    document.aircraft.src='f15e.gif'

    Вывод, созданный с использованием функций JavaScript

    Рисунок 11.2 Вывод, созданный с использованием функций JavaScript

    Вывод, созданный с использованием функций JavaScript>
    Следующая строка создаёт вывод функции bar:
    document.write("
    ")
    Заметьте, что в определении bar использованы знаки одинарных кавычек вместо двойных. Вы обязаны делать так при обозначении закавыченной строки внутри строкового литерала. Затем вызов bar с аргументом 25 производит вывод, эквивалентный следующему HTML:


    write сопутствующий метод writeln, который добавляет последовательность символов "новая строка" (возврат каретки или возврат каретки + прогон строки, в зависимости от платформы) в конец своего вывода. Поскольку HTML обычно игнорирует символы новой строки, разницы между write и writeln нет, за исключением положения внутри таких тэгов, как PRE.

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

    Свойства объекта document зависят от содержимого. То есть они создаются на основе HTML документа. Например, document имеет свойства для каждой формы и каждого якоря /anchor документа.
    Предположим, Вы создаёте страницу simple.html, которая содержит следующий HTML:
    A Simple Document



    Enter a value:


    Check if you want:

    onClick="update(this.form)"> Option #1


    onClick="update(this.form)">



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

    Пример значений свойств объектов

    Таблица 11.1 Пример значений свойств объектов


    Свойство
    Значение
    document.title "A Simple Document"
    document.fgColor #000000
    document.bgColor #ffffff
    location.href "http://www.royalairways.com/samples/simple.html"
    history.length 7

    Обратите внимание, что значение свойства document.title отражает значение, специфицированное тэгом TITLE. Значения свойств document.fgColor (цвет текста) и document.bgColor (цвет фона) не были установлены в HTML, поэтому они базируются на значениях по умолчанию, специфицированных в диалоговом окне Preferences (в меню Edit Navigator'а).
    Поскольку в документе имеется форма, имеется также объект Form под названием myform (на основе атрибута NAME формы), который имеет дочерние объекты для checkbox и для button. Каждый из этих объектов имеет имя на основе атрибута NAME тэга HTML, определяющего этот объект:
  • document.myform - форма

  • document.myform.Check1 - checkbox/переключатель

  • document.myform.button1 - button/кнопка

  • Form-объект myform имеет другие свойства на основе атрибутов тэга FORM, например,

  • action это http://www.royalairways.com/samples/mycgi.cgi - URL по которому форма отправляется.

  • method это "get" - на основе значения атрибута METHOD.

  • length равен 3, поскольку на форме размещены три элемента.

  • Объект Form имеет дочерние объекты button1 и text1, соответствующие кнопке и текстовому полю на форме. Эти объекты имеют свои собственные свойства на основе значений своих HTML-атрибутов, например,

  • button1.value имеет значение "Press Me"

  • button1.name имеет значение "Button1"

  • text1.value имеет значение "blahblah"

  • text1.name имеет значение "text1"

  • Вы обращаетесь к этим свойствам, используя из полное именование, например, document.myform.button1.value. Это полное имя, основанное на иерархии объектов Navigator'а, начинается с document, затем идёт имя формы, myform, затем - имя элемента, button1, и, наконец, имя свойства.

    Предопределённые массивы JavaScript

    Таблица 11.2 Предопределённые массивы JavaScript

    ОбъектСвойство
    Описание
    documentanchorsОтражает тэги документа, содержащие атрибут NAME, в порядке расположения в исходном коде.
    appletsОтражает тэги в порядке расположения в исходном коде.
    embedsОтражает тэги в порядке расположения в исходном коде.
    formsОтражает тэги
    в порядке расположения в исходном коде.
    imagesОтражает тэги в порядке расположения в исходном коде (изображения, созданные конструктором Image(), не включаются в массив images).
    layersОтражает тэги и в порядке расположения в исходном коде.
    linksОтражает тэги , , и объекты Link, созданные методом link, в порядке расположения в исходном коде.
    FormelementsОтражает элементы формы (такие как объекты Checkbox, Radio и Text) в порядке расположения в исходном коде.
    FunctionargumentsОтражает аргументы функции.
    navigatormimeTypesОтражает все MIME-типы, поддерживаемые клиентом (внутренне, через вспомогательные приложения или через plug-in'ы).
    pluginsОтражает все plug-in'ы, установленные на клиенте, в порядке расположения в исходном коде.
    selectoptionsОтражает опции объекта Select (тэги
    windowframesОтражает все тэги в окне, содержащем тэг , в порядке расположения в исходном коде.
    historyОтражает вхождения history окна.

    Вы можете индексировать порядковыми числами или по именам (если определены). Например, если второй тэг имеет в атрибуте NAME значение "myForm", Вы можете обратиться к форме document.forms[1], или document.forms["myForm"] или document.myForm.
    Например, определён следующий элемент:

    Если Вы хотите обратиться к этому элементу формы по имени, можно специфицировать document.forms["Comments"].
    Все предопределённые массивы JavaScript имеют свойство length, которое указывает количество элементов массива. Например, чтобы получить количество форм в документе, используйте свойство length: document.forms.length.

    JavaScript 1.0.

    Вы обязаны индексировать массивы порядковыми числами, например document.forms[0].

    Клиентский JavaScript 1.3 Руководство

    Использование фрэймов

    Набор фрэймов/frameset это специальный тип окна, в котором выводятся несколько независимо прокручиваемых фрэймов/кадров/frames в одном экране, каждый со своим собственным URL. Фрэймы набора фрэймов могут указывать на различные URL и могут быть целями для других URL, все в одном окне. Серия фрэймов в наборе фрэймов\frameset образует HTML-страницу.
    На рисунке показано окно с тремя фрэймами. Левый фрэйм называется listFrame; правый - contentFrame; нижний - navigateFrame.

    Навигация по окнам и фрэймам

    Несколько окон Navigator'а могут быть открыты в одно время. Пользователь может перемещаться между этими окнами, щёлкая по ним, чтобы сделать активными, или передавая им фокус. Если окно имеет фокус, оно переходит на передний план и несколько изменяет свой вид. Например, может измениться цвет строки заголовка. Визуальное расположение зависит от используемой платформы.
    Вы можете передать фокус окну программно, передавая фокус объекту в этом окне или специфицируя окно как цель гиперссылки. Хотя Вы можете изменять значения объектов в другом окне, это не сделает второе окно активным: активным останется текущее окно.
    Вы перемещаетесь по фрэймам так же, как по окнам.

    Обновление фрэйма

    Обновление фрэйма

    Вы может обносить содержимое фрэйма с помощью свойства location, установив URL.
    Например, Вы используете frameset, описанный в Примере 2 в предыдущем разделе. Если Вы хотите, чтобы пользователи могли закрывать фрэйм, содержащий алфавитный список артистов или список по категориям (во фрэйме listFrame) и вид только названий произведений, отсортированных по музыкантам (в данный момент - во фрэйме contentFrame), Вы можете добавить следующую функцию в navigateFrame:
    onClick="top.frames[0].location='artists.html'">
    Когда пользователь щёлкает по этой кнопке, файл artists.html загружается во фрэйм upperFrame; фрэймы listFrame и contentFrame закрываются и больше не существуют.

    Обращение к фрэймам и навигация по ним

    Обращение к фрэймам и навигация по ним

    Поскольку фрэймы являются типом окна, Вы обращаетесь к фрэймам и перемещаетесь по ним, как по окнам. См. "Обращение к Окнам и Фрэймам" и "Навигация по Окнам и Фрэймам".

    Обращение к окнам и фрэймам

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

    Обращение к окну при отправке формы или из гиперссылки

    Обращение к окну при отправке формы или из гиперссылки

    Вы используете имя окна (не переменную окна) при обращении к окну как к цели/target при отправке формы или из гиперссылки (атрибут TARGET тэга FORM или A). Специфицируемое окно это окно, в которое загружается ссылка, или, для формы, окно, где выводится ответ сервера.
    Следующий пример создаёт гиперссылку на второе окно. Имеется кнопка, которая открывает пустое окно window2, гиперссылка, загружающая файл doc2.html во вновь открытое окно, и кнопка, закрывающая окно.

    onClick="msgWindow=window.open('','window2',
    'resizable=no,width=200,height=200')">

    Load a file into window2

    onClick="msgWindow.close()">

    Если пользователь выбирает сначала кнопку Open Second Window, а затем гиперссылку, Communicator открывает небольшое окно, специфицированное в кнопке, а затем загружает в него файл doc2.html.
    Если пользователь выбирает гиперссылку до создания окна window2 с помощью кнопки, Communicator создаёт window2 с параметрами по умолчанию и загружает doc2.html в это окно. Если пользователь позднее щёлкает кнопку Open Second Window button, Communicator изменяет параметры уже открытого окна на специфицированные в обработчике события.

    Обращение к свойствам, методам и обработчикам

    Обращение к свойствам, методам и обработчикам

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

  • self или window: self и window
    являются синонимами текущего окна, и Вы можете использовать их по выбору для обращения к текущему окну. Например, Вы можете закрыть текущее окно, вызвав window.close()
    или self.close().

  • top или parent: top и parent также являются синонимами, которые могут использоваться как имена окна.

    top можно использовать для любого окна; оно ссылается на самое верхнее окно Navigator'а.

    parent можно использовать для фрэйма; оно ссылается на окно с тэгом frameset, содержащее данный фрэйм. Например, для фрэйма frame1, оператор parent.frame2.document.bgColor="teal" изменяет фон фрэйма frame2 на teal, где frame2 это дочерний фрэйм текущего frameset.

  • Имя переменной окна: переменная окна это переменная, специфицированная при открытии окна. Например, msgWindow.close() закрывает окно msgWindow.

  • Отсутствие имени окна: поскольку существование текущего окна подразумевается, Вы не обязаны обращаться к окну по имени, когда вызываете его методы и присваиваете значения свойств. Например, close() закрывает текущее окно. Однако, когда Вы открываете или закрываете окно обработчиком события, Вы обязаны специфицировать window.open() или window.close() вместо простого open() или close(). Из-за области видимости static-объектов в JavaScript, вызов close() без специфицирования имени объекта эквивалентен document.close().

  • Дополнительно об этих техниках см. объект window в книге
    Клиентский JavaScript.
    Справочник.

    Открытие и закрытие окон

    Окно создаётся автоматически при запуске Navigator'а; Вы можете открыть другое окно, выбрав New и Navigator Window в меню File. Вы можете закрыть окно, выбрав Close или Exit в меню File. Вы можете также открывать и закрывать окна программно с помощью JavaScript.

    Открытие окна

    Открытие окна

    Можно создать окно методом open. Следующий оператор создаёт окно msgWindow, которое отображает содержимое файла sesame.html:
    msgWindow=window.open("sesame.html")
    Следующий оператор создаёт окно homeWindow, которое отображает домашнюю страницу Netscape:
    homeWindow=window.open("http://home.netscape.com")
    Окно может иметь два имени. Следующий оператор создаёт окно с двумя именами. Первое имя, msgWindow, это переменная, которая ссылается на объект window. Этот объект содержит информацию о свойствах, методах и контейнерах окна. При создании окна Вы можете также предоставить второе имя, в данном случае - displayWindow, для обращения к окну как к цели/target при отправке формы или при переходе по гиперссылке.
    msgWindow=window.open("sesame.html","displayWindow")
    Имя окна не требуется при создании окна. Но окно обязано иметь имя, если Вы хотите обратиться к нему из другого окна.
    При открытии окна Вы можете специфицировать атрибуты, такие как высота/height и ширина/width, панель утилит/toolbar, адресная строка/location field или полосы прокрутки/scrollbars. Следующий оператор создаёт окно без панели утилит, но с полосами прокрутки:
    msgWindow=window.open
    ("sesame.html","displayWindow","toolbar=no,scrollbars=yes")
    Об именах окно см. дополнительно "Обращение к окнам и фрэймам". Об атрибутах окна см. метод open объекта window в книге Клиентский JavaScript. Справочник.

    Следующий оператор создаёт frameset, показанный

    Следующий оператор создаёт frameset, показанный ранее на рисунке:







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

    обращение к текущему окну.

    Следующий оператор ссылается на форму musicForm в текущем окне. Оператор выводит диалог alert, если переключатель/checkbox отмечен.
    if (document.musicForm.checkbox1.checked) {
    alert('The checkbox on the musicForm is checked!')}

    передача фокуса объекту в другом окне.

    Следующий оператор передаёт фокус Text-объекту city в окне checkboxWin. Поскольку Text-объект получает фокус, окно также получает фокус и становится активным. В примере имеется также оператор, создающий окно checkboxWin.
    checkboxWin=window.open("doc2.html")
    ...
    checkboxWin.document.musicForm.city.focus()

    Альтернативно Вы можете создать окно

    Альтернативно Вы можете создать окно типа вышеприведённого, в котором два верхних фрэйма имеют родителя отдельно от navigateFrame. Набор фрэймов/frameset верхнего уровня может быть определён так:




    Файл muskel3.html содержит каркас верхних фрэймов и определяет следующий frameset:




    На следующем рисунке показана иерархия фрэймов.
    upperFrame и navigateFrame имеют общего родителя - окно top.
    listFrame и contentFrame - имеют общего родителя upperFrame.

    обращение к другому окну.

    Следующие операторы ссылаются на форму musicForm, находящуюся в окне checkboxWin. Операторы определяют, выбран ли checkbox, выбирают checkbox, определяют, выбрана ли вторая опция объекта Select, и выбирают вторую опцию объекта Select. Даже если значения объектов изменяются в другом окне (checkboxWin), текущее окно остаётся активным: отметка переключателя и выбор selection-опции не передают фокус окну.
    // определить, отмечен ли checkbox
    if (checkboxWin.document.musicForm.checkbox2.checked) {
    alert('The checkbox on the musicForm in checkboxWin is checked!')}// отметить checkbox
    checkboxWin.document.musicForm.checkbox2.checked=true// определить, выбрана ли опция объекта Select
    if (checkboxWin.document.musicForm.musicTypes.options[1].selected)
    {alert('Option 1 is selected!')}// выбрать опцию объекта Select
    checkboxWin.document.musicForm.musicTypes.selectedIndex=1

    обращение к фрэйму в другом окне.

    Следующий оператор обращается к фрэйму frame2, который находится в окне window2. Оператор изменяет цвет фона frame2 на violet. Имя фрэйма, frame2, обязано быть специфицировано в тэге FRAMESET, создающем набор фрэймов.
    window2.frame2.document.bgColor="violet"

    иерархии фрэймов

    Рисунок 12.2 Пример иерархии фрэймов

    иерархии фрэймов
    Вы можете обратится к фрэймам, используя массив frames так, как показано ниже. (О массиве frames см. объект window в книге Клиентский JavaScript. Справочник.)

  • listFrame is top.frames[0]

  • contentFrame is top.frames[1]

  • navigateFrame is top.frames[2]


  • Ещё один пример иерархии фрэймов

    Рисунок 12.3 Ещё один пример иерархии фрэймов

    Ещё один пример иерархии фрэймов
    Вы можете обратится к предыдущим фрэймам, используя массив frames так, как показано ниже. (О массиве frames см. объект window в книге Клиентский JavaScript. Справочник.)
  • upperFrame это top.frames[0]

  • navigateFrame это top.frames[1]

  • listFrame это upperFrame.frames[0] или top.frames[0].frames[0]

  • contentFrame это upperFrame.frames[1] или top.frames[0].frames[1]

  • Пример создания фрэймов см. в разделе "Создание и Обновление Фрэймов: Пример".

    Создание фрэйма

    Создание фрэйма

    Вы создаёте фрэйм тэгом FRAMESET в HTML-документе; единственное предназначение этого тэга - определить фрэймы на странице.

    Создание и обновление фрэймов: пример

    Создание и обновление фрэймов: пример

    Если Вы создаёте набор фрэймов/frameset из предыдущего раздела для представления информации музыкального клуба, фрэймы и их HTML-файлы могут иметь следующее содержимое:
  • category.html, во фрэйме listFrame, содержит список музыкантов, отсортированный по категориям.

  • titles.html, во фрэйме contentFrame, содержит алфавитный список музыкантов и произведений каждого.

  • navigate.html, во фрэйме navigateFrame, содержит гипертекстовые ссылки для выбора представления музыкантов в списке listFrame: по алфавиту или по категориям. Также в это файле имеется ссылка на описание музыкантов.
  • Дополнительный файл, alphabet.html, содержит список музыкантов, отсортированный по алфавиту. Этот файл выводится во фрэйме listFrame, если пользователь щёлкает по гиперссылке для отображения в алфавитном порядке.

  • Файл category.html (список по категориям) содержит код типа такого:
    Music Club Artists
    Jazz
  • Toshiko Akiyoshi
  • John Coltrane
  • Miles Davis
  • Dexter GordonSoul
  • Betty Carter
  • Ray Charles
    ...
    Файл alphabet.html (алфавитный список) содержит код типа такого:
    Music Club Artists
  • Toshiko Akiyoshi
  • The Beatles
  • Betty Carter
  • Ray Charles
    ...

    Файл navigate.html ( ссылки внизу экрана) содержит код типа нижеприведённого. Обратите внимание, что target для файла artists.html это "_parent." Если пользователь щёлкает по гиперссылке, все окно перерисовывается, потому что окно top является родителем для navigateFrame.

    Alphabetical
       
    By category
       

    Musician Descriptions


    Файл titles.html (главный файл, отображаемый в правом фрэйме) содержит код типа такого:

    Toshiko Akiyoshi


    Interlude

    The Beatles


    Please Please Me

    Betty Carter


    Ray Charles and Betty Carter
    ...

    Закрытие окна

    Закрытие окна

    Вы можете закрыть окно методом close. Вы не можете закрыть фрэйм, не закрыв родительское окно.
    Каждый из следующих операторов закрывает текущее окно:
    window.close()
    self.close()
    close()
    Не используйте третью форму, close(), в обработчиках событий. В зависимости от того, как JavaScript вычисляет объект, на который ссылается вызов метода, Вы можете получить в обработчике не тот объект.
    Следующий оператор закрывает окно msgWindow:
    msgWindow.close()

    Клиентский JavaScript 1.3 Руководство

    Использование JavaScript-URL

    Вам, возможно, уже знакомы стандартные типы URL: http:, ftp:, file: и так далее. В Navigator'е Вы можете использовать также URL типа javascript: для выполнения операторов JavaScript вместо загрузки документа. Вы просто используете строку, начинающуюся с javascript:, в качестве значения атрибута HREF тэгов anchor. Например, Вы можете определить такую гиперссылку для перезагрузки текущей страницы:
    Reload Now
    В общем, Вы можете поместить любой оператор или вызов функции после префикса javascript: в URL.
    Можно по-разному использовать JavaScript-URL для добавления функциональности в Ваши приложения. Например, можно выполнить инкремент счётчика p1 в родительском фрэйме, если пользователь щёлкает по гиперссылке, с помощью такой функции:
    function countJumps() {
    parent.p1++
    window.location=page1
    }
    Для вызова этой функции используйте JavaScript-URL в стандартной гиперссылке HTML:
    Page 1
    Здесь предполагается, что page1 это строка, представляющая URL.
    Если значение выражения, идущего после URL-префикса javascript:, вычисляется в undefined, новый документ не загружается. Если значение вычисляется в определённый тип, значение конвертируется в строку, которая специфицирует источник загружаемого документа.

    Использование клиентских карт изображений

    Клиентская карта изображений определяется тэгом MAP. Вы можете определить области на изображении, которые являются гиперссылками на различные URL; области могут быть прямоугольными, круглыми и многоугольными.
    Вместо стандартных URL Вы можете использовать в клиентских картах JavaScript-URL, например:

    HREF ="javascript:top.close(); window.location = newnav.html">
    HREF="contents.html" target="javascript:alert(`Loading
    Contents.'); top.location = contents.html">


    Использование кук: пример

    Использование кук: пример

    Используя cookie-функции, определённы в предыдущем разделе, Вы можете создать простую страницу, которую пользователи могут заполнить для "регистрации" при посещении Вашей страницы. Если они будут повторно посещать Вашу страницу в течение года, они будут получать персональное приветствие.
    Вам необходимо определить дополнительно ещё одну функцию в HEAD/шапке документа. Эта функция, register, создаёт куку TheCoolJavaScriptPage и значение, передаваемое ей - в качестве аргумента.
    function register(name) {
    var today = new Date()
    var expires = new Date()
    expires.setTime(today.getTime() + 1000*60*60*24*365)
    setCookie("TheCoolJavaScriptPage", name, expires)
    }
    BODY документа использует getCookie (определённую в предыдущем разделе) для проверки существования куки TheCoolJavaScriptPage и выводит приветствие, если кука имеется. Имеется также форма, которая вызывает register для добавления куки. Обработчик onClick вызывает также history.go(0) для перерисовки страницы.

    Register Your Name with the Cookie-Meister



    Enter your name. When you return to this page within a year, you will be greeted with a personalized greeting.


    Enter your name:

    onClick="register(this.form.username.value); history.go(0)">


    Использование кук в JavaScript

    Использование кук в JavaScript

    Свойство document.cookie это строка, содержащая имена и значения всех кук Navigator'а. Вы можете использовать это свойство для работы с куками в JavaScript.
    Вот что Вы можете делать с куками:

  • Устанавливать значение куки, специфицируя, по выбору, срок действия куки.

  • Получить значение куки, задав её имя.

  • Для выполнения этих задач удобно определить функцию. Вот, например, функция, устанавливающая значение и дату окончания действия куки:
    // Установить значение куки. Дата окончания действия - не обязательна.
    //
    function setCookie(name, value, expire) {
    document.cookie = name + "=" + escape(value)
    + ((expire == null) ? "" : ("; expires=" + expire.toGMTString()))
    }
    Обратите внимание на использование функции escape для кодирования специальных символов (точки с запятой, запятой, пробелов) в строке-значении. Эта функция принимает, что имена кук не содержат специальных символов.
    Следующая функция возвращает значение куки, задавая имя куки:
    function getCookie(Name) {
    var search = Name + "="
    if (document.cookie.length > 0) { // если есть какие-либо куки
    offset = document.cookie.indexOf(search)
    if (offset != -1) { // если кука существует
    offset += search.length
    // установить индекс начала значения
    end = document.cookie.indexOf(";", offset)
    // установить индекс конца значения куки
    if (end == -1)
    end = document.cookie.length
    return unescape(document.cookie.substring(offset, end))
    }
    }
    }
    Обратите внимание на использование функции unescape для декодирования специальных символов в значении куки.

    Использование кук

    Куки Netscape это механизм хранения данных на клиенте в файле cookies.txt. Поскольку HyperText Transport Protocol (HTTP) это бесстатусный/stateless протокол, куки являются способом обслуживания информации в промежутках между клиентскими запросами. В этом разделе обсуждаются основы использования кук/cookies и дан простой пример. Полное описание кук см. в книге
    Клиентский JavaScript.
    Справочник.
    Кука это небольшой блок информации, иногда имеющий строк действия и добавляемый в cookie-файл в следующем формате:
    name=value;expires=expDate;
    name это имя хранимых данных, а value это значение. Если name и value содержат одну запятую, точку с запятой или пробелы, Вы обязаны использовать функцию escape для их кодирования и функцию unescape - для декодирования.
    expDate это дата окончания срока действия в GMT-формате даты:
    Wdy, DD-Mon-YY HH:MM:SS GMT
    Хотя он слегка отличается от формата строки даты, возвращаемой методом toGMTString объекта Date, метод toGMTString можно использовать для установки срока действия куки.
    Дата-срок действия куки является параметром по выбору/optional, указывающим срок действия куки. Если expDate не специфицирован, кука перестаёт действовать после выхода пользователя из текущей сессии Navigator'а. Navigator обслуживает и запрашивает куку, только если строк действия куки ещё не передан.
    О функциях escape и unescape см. книгу Клиентский JavaScript.
    Справочник.

    Использование серверных карт изображений

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

    Если Вы щёлкаете по изображению с атрибутом ISMAP, Navigator запрашивает URL в такой форме:
    URL?x,y
    где URL это документ, специфицированный значением атрибута HREF, а x и y это горизонтальная и вертикальная координаты указателя мыши (в пикселах от верхнего левого угла изображения) во время щелчка. (Изображение "about:logo" встроено в Navigator и отображает логотипом Netscape.)
    Запросы карт традиционно отправляются на сервер, где CGI-программа выполняет функцию просмотра базы данных. С помощью клиентского JavaScript, однако, Вы можете просматривать на стороне клиента. Можно использовать свойство search объекта location для разбора координат x и y и выполнения соответствующей акции. Например, у Вас имеется файл img.html со следующим содержимым:

    Click on the image





    Если Вы щёлкаете по изображению, Navigator перезагружает страницу (поскольку атрибут HREF специфицирует тот же самый документ), добавляя в URL координаты x и y щелчка мыши. Операторы блока else отображают затем координаты x и y. На практике Вы можете перенаправлять на другую страницу (устанавливая location) или выполнять какое-нибудь другое действие на основе значений x и y.

    Использование статусной строки

    Вы можете использовать два свойства объекта window, status и defaultStatus, для отображения сообщений в статусной строке Navigator'а в нижней части окна. Navigator обычно использует status bar для вывода таких сообщений, как "Contacting Host..." и "Document: Done." Сообщение defaultStatus появляется, если в статусной строке больше ничего нет. Свойство status отображает временное сообщение, как, например, при проведении указателя мыши над гиперссылкой.
    Можно настроить эти свойства для отображения специальных сообщений. Например, чтобы вывести специальное сообщение по окончании загрузки документа, просто установите defaultStatus. Например,
    defaultStatus = "Some rise, some fall, some climb...to get to Terrapin"

    Массив mimeTypes

    Массив mimeTypes

    mimeTypes это массив всех MIME-типов, поддерживаемых клиентом (внутренне - через вспомогательные приложения, или с помощью plug-in'ов). Каждый элемент массива является MimeType-объектом, который имеет свойства своего типа, описание, расширение файла и подключённые plug-in'ы.
    Например, в следующей таблице даны значения для вывода JPEG-изображений.

    Массив plugins

    Массив plugins

    plugins это массив всех plug-in'ов, установленных в данный момент на клиенте. Каждый элемент массива является Plugin-объектом, имеющим свойства для своего имени, имени файла и описание, а также массив MimeType-объектов для MIME-тпов, поддерживаемых данным plug-in'ом. Пользователь может получить список установленных plug-in'ов, выбрав меню About Plug-ins из Help. Например, в следующей таблице резюмируются значения для plug-in'ов LiveAudio.

    Ограничения

    Ограничения

    Куки имеют следующие ограничения:

  • всего 300 кук в cookie-файле.

  • 4 Kb на одну куку как сумму имени и значения.

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

  • Куки могут ассоциироваться с одной или несколькими директориями. Если все Ваши файлы находятся в одной директории/каталоге, Вы не должны беспокоиться об этом. Если Ваши файлы находятся в разных каталогах, Вам может понадобится использовать дополнительный параметр пути для каждой куки. Дополнительно см. книгу Клиентский JavaScript.
    Справочник.

    Определение установленных Plug-in'ов

    Вы можете использовать JavaScript для того чтобы определить, имеется ли у пользователя определённый установленный plug-in; затем Вы можете отобразить данные внедрённого plug-in'а, если plug-in установлен, или вывести какую-нибудь другую информацию (например, рисунок или текст), если не установлен. Вы можете также определить, может ли клиент обрабатывать определённый MIME-тип (Multipart Internet Mail Extension). В этом разделе даны объекты и свойства, необходимые для обработки plug-in'ов и MIME-типов. Более детальную информацию об этих объектах и свойствах см. в книге Клиентский JavaScript.
    Справочник.
    Объект navigator имеет два свойства для проверки установленных plug-in'ов: массив mimeTypes и массив plugins.

    Создание подсказок обработчиками onMouseOver и onMouseOut

    Создание подсказок обработчиками onMouseOver и onMouseOut

    По умолчанию, если Вы проводите указатель мыши над гиперссылкой, в статусной строке отображается URL назначения гиперссылки. Вы можете установить status в обработчиках onMouseOut и onMouseOver гиперссылки или области изображения для отображения подсказок в статусной строке. Обработчик события обязан возвращать true для установки значения status. Например,
    onMouseOver="window.status='Click to display contents';return true">
    Contents

    В это примере подсказка "Click to display contents" выводится в статусной строке, когда указатель мыши проходит над гиперссылкой.

    Значения свойства MimeType для рисунков JPEG


    Таблица 13.1 Значения свойства MimeType для рисунков JPEG


    Выражение
    Значение
    navigator.mimeTypes["image/jpeg"].typeimage/jpeg
    navigator.mimeTypes["image/jpeg"].descriptionJPEG Image
    navigator.mimeTypes["image/jpeg"].suffixesjpeg, jpg, jpe, jfif, pjpeg, pjp
    navigator.mimeTypes["image/jpeg"].enabledPluginnull

    Следующий скрипт проверяет, может ли клиент работать с клипами QuickTime:
    var myMimetype = navigator.mimeTypes["video/quicktime"]
    if (myMimetype)
    document.writeln("Click here to см. a " +
    myMimetype.description)
    else
    document.writeln("Too bad, can't show you any movies.")

    Значения свойств Plugin для plug-in'а LiveAudio


    Таблица 13.2 Значения свойств Plugin для plug-in'а LiveAudio

    Выражение
    Значение
    navigator.plugins['LiveAudio'].name LiveAudio
    navigator.plugins['LiveAudio'].description LiveAudio - Netscape Navigator sound playing component
    navigator.plugins['LiveAudio'].filename d:\nettools\netscape\nav30\
    Program\plugins\NPAUDIO.DLL
    navigator.plugins['LiveAudio'].length 7

    В Таблице 13.2 значение свойства length указывает, что navigator.plugins['LiveAudio'] имеет массив объектов MimeType, содержащий 7 элементов. Значения свойств второго элемента этого массива показаны в следующей таблице.

    Клиентский JavaScript 1.3 Руководство

    Атрибут ARCHIVE

    Атрибут ARCHIVE

    Все маркированные скрипты (инлайн-скрипт, обработчик события, файл JavaScript или объект JavaScript) требуют наличия в тэге SCRIPT атрибута ARCHIVE, значением которого является имя JAR-файла, содержащего цифровую подпись. Например, чтобы маркировать JavaScript-файл, Вы можете использовать такой тэг:

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

    onClick="alert('A signed script')" ID="b">

    Если Вы специфицируете не более одного JAR-файла, Вам нужно специфицировать файл только однократно. Включите атрибут ARCHIVE в первый скрипт на HTML-странице, и остальные скрипты на странице используют этот же файл. Например:


    Атрибут ID

    Атрибут ID

    Инлайн-скрипты и скрипты в обработчиках требуют наличия атрибута ID. Значением этого атрибута является строка, которая соотносит скрипт с его подписью в JAR-файле. ID обязан быть уникальным в JAR-файле.
    Если тэг содержит более одного скрипта обработчика события, Вам нужен только один ID. Весь тэг маркируется как один блок.
    В следующем примере первые три скрипта используют один JAR-файл. Третий скрипт выполняет доступ к JavaScript-файлу, поэтому он не использует атрибут ID. Четвёртый скрипт использует другой JAR-файл, и его ID "a" уникален для этого файла.
    onLoad="alert('A signed script using firstArchive.jar')"
    onLoad="alert('One ID needed for these event handler scripts')"
    ID="b">




    Будьте осторожны с тем, что экспортируете

    Будьте осторожны с тем, что экспортируете

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

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

    Цели/Targets

    Цели/Targets

    Типы информации, которую Вы можете получить, называются targets. Они перечислены в таблице.
    Target/ЦельОписание
    UniversalBrowserReadПозволяет читать привилегированные данные из браузера. Это даёт возможность скрипту передавать одну проверку источника всему документу.
    UniversalBrowserWriteПозволяет модифицировать привилегированные данные в браузере. Это даёт возможность скрипту передавать одну проверку источника всему документу.
    UniversalBrowserAccessПозволяет читать и модифицировать привилегированные данные из браузера. Это даёт возможность скрипту передавать одну проверку источника всему документу.
    UniversalFileReadДаёт скрипту возможность читать любой файл на жёстком диске или другом носителе, подключённом к компьютеру.
    UniversalPreferencesReadДаёт скрипту возможность читать настройки, используя метод navigator.preference.
    UniversalPreferencesWriteДаёт скрипту возможность устанавливать настройки, используя метод navigator.preference.
    UniversalSendMailДаёт программе возможность отправлять посту на имя пользователя.

    Полный список targets см. в документе Netscape System Targets.

    Функции импорта и экспорта

    Функции импорта и экспорта

    Вам могут понадобиться интерфейсы для вызова в засекреченных контейнерах (окнах и слоях). Для этого используйте операторы import и export. Экспортирование имени функции делает её доступной для импорта скриптами, находящимися за пределами контейнера, без проверки контейнера.
    Вы можете импортировать и экспортировать только функции - как функции верхнего уровня (ассоциированные с объектом window), так и методы некоторых других объектов. Вы не можете импортировать или экспортировать объекты целиком или свойства, которые не являются функциями.
    Импортирование функции в Вашу область видимости создаёт новую функцию с тем же именем, что и у импортируемой функции. Вызов такой функции вызывает соответствующую функцию из засекреченного контейнера.
    Для использования import и export Вы обязаны явно установить атрибут LANGUAGE тэга SCRIPT в "JavaScript1.2":


    Использование расширенных привилегий

    Использование расширенных привилегий

    Как и маркированные объекты Java, маркированные скрипты используют вызовы Netscape-классов безопасности Java для запрашивания расширенных привилегий. Java-классы расширяются в Java Capabilities API.
    В простейшем случае Вы добавляете одну строку кода, запрашивающего разрешение на доступ к определённой цели, представляющей ресурс, доступ к которому Вы хотите получить. (См. "Цели".) Например:
    netscape.security.PrivilegeManager.enablePrivilege("UniversalSendMail")
    Когда скрипт вызывает эту функцию, подпись проверяется и, если подпись верна, даются расширенные привилегии. Если нужно, диалог выводит информацию об авторе приложения и предоставляет пользователю опцию для разрешения или запрещения расширенных привилегий.
    Привилегии даются только в области видимости запрашивающей функции и только после того как запрос удовлетворён в этой функции. Эта область видимости функции включает любые функции, вызываемые запрашивающей функцией. Когда скрипт выходит из запрашивающей функции, привилегии перестают действовать.
    Следующий пример демонстрирует это, печатая такой текст:
    7: disabled
    5: disabled
    2: disabled
    3: enabled
    1: enabled
    4: enabled
    6: disabled
    8: disabled
    Функция g запрашивает расширенные привилегии, и только команды и функции, которые вызываются после запроса и внутри функции g, получают привилегии.


    Использование разрушения данных

    В JavaScript 1.1 имеется возможность, называемая data tainting\разрушение данных, которая остаётся ограничением безопасности той же самой политики одного источника, но предоставляет средство для секретного доступа к специфическим компонентам страницы. Эта возможность имеется только в JavaScript 1.1; в JavaScript 1.2 она удалена.
  • Если разрушение данных включено, JavaScript может смотреть свойства в другом окне, независимо от того, с какого сервера было загружено второе окно. Однако автор второго окна разрушает (маркирует) значения свойств или иные данные, которые должны быть секретными или закрытыми, и JavaScript не может передать эти разрушенные данные любому серверу без разрешения пользователя.

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

  • Чтобы включить разрушение, конечный пользователь устанавливает переменную окружения/environment variable, как описано в разделе "Включение Разрушения".

    Использование утилиты Netscape Signing Tool

    Использование утилиты Netscape Signing Tool

    После написания скрипта Вы маркируете его с помощью утилиты Netscape Signing Tool. См. Signing Software with Netscape Signing Tool 1.1.

    Изолирование немаркированного слоя внутри маркированного контейнера

    Изолирование немаркированного слоя внутри маркированного контейнера

    Для создания немаркированного слоя внутри маркированного контейнера Вы должны выполнить некоторые дополнительные шаги, чтобы скрипты в немаркированном слове работали правильно.
  • Вы обязаны установить в свойство __parent__ объекта layer значение null, чтобы просмотры переменных, выполняемые скриптом в немаркированном слое, не доходили по цепочке родителей до объекта window и не пытались получить доступ к свойствам объекта window, которые защищены проверкой контейнера.

  • Поскольку стандартные объекты (String, Array, Date и т.д.) определяются обычно в объекте window, а не в слое, Вы обязаны вызывать метод initStandardObjects объекта layer. Это создаст копии стандартных объектов в области видимости слоя.


  • Как работает разрушение данных

    Как работает разрушение данных

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

    Маркированные скрипты. Введение.

    Маркированные скрипты. Введение.

    Маркированный скрипт запрашивает расширенные привилегии, получая доступ к закрытой информации. Он запрашивает эти привилегии через использование LiveConnect и Java-классов, называемых Java Capabilities API. Эти классы добавляют возможности и уточняют управление, предоставляемое стандартным Java-классом SecurityManager. Вы можете использовать эти классы для осуществления высокоточного контроля в так называемом "sandbox/песочном ящике" - термин Java для жёстких ограничений, в пределах которых код Java обязан выполняться.
    Решения по управлению доступом сводятся к тому, кто и что может делать. В этой модели principal\принципал представляет "кто", target\цель представляет "что", а privileges\привилегии, ассоциированные с принципалом, представляют авторизацию (или запрет авторизации) принципалу для доступа к специфической цели.
    После написания скрипта Вы маркируете его, используя утилиту Netscape Signing Tool. Эта утилита ассоциирует цифровую подпись со скриптом на HTML-странице. Владельцем это цифровой подписи является определённый принципал (реальный объект, такой как Netscape или John Smith). Одна HTML-страница может иметь скрипты, маркированные разными принципалами. Цифровая подпись помещается в Java Archive (JAR) -файл. Если Вы маркируете инлайн-скрипт, обработчик события или объект JavaScript, Netscape Signing Tool сохраняет только подпись и идентификатор для скрипта в JAR-файле. Если Вы маркируете JavaScript-файл утилитой Netscape Signing Tool, она также сохраняет источник в JAR-файле.
    Ассоциированный принципал позволяет пользователю подтверждать правильность сертификата, используемого для маркировки скрипта. Он также позволяет пользователю убедиться, что данный скрипт подделан после маркировки. Пользователь может затем решить, дать ли привилегии на основе проведённой идентификации сертификата пользователя и проверки целостности скрипта.
    Запомните, что пользователь может запретить выдачу привилегий, запрошенных Вашим скриптом - Вы должны создавать Ваши скрипты так, чтобы они адекватно реагировали на такую ситуацию.

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



  • Netscape Object Signing: Establishing Trust for Downloaded Software - обзор маркировки объектов. Разберитесь в этом материале, прежде чем использовать маркировку скриптов.


  • Introduction to the Capabilities Classes - детальная информация об использовании Java Capabilities API. Поскольку маркированные скрипты используют этот API для запрашивания привилегий, Вам необходимо разобраться в этой информации.


  • Java Capabilities API - введение в Java API, используемый для маркировки объектов. Содержится информация о том, где можно ещё прочитать об этом API.


  • Signing Software with Netscape Signing Tool 1.1 - описывает использование утилиты Netscape Signing Tool для создания маркированных скриптов.


  • Object-Signing Resources - список документов и ресурсов по вопросам маркировки объектов.


  • Маркировка скриптов

    Маркировка скриптов

    В процессе разработки скрипта, который Вы, возможно, промаркируете, Вы можете использовать принципалы кодовой базы для проверки, как описано в разделе "Принципалы Кодовой Базы". После завершения модификации скрипта, Вам необходимо промаркировать его.
    Чтобы предоставить любому скрипту расширенные привилегии, все скрипты на этой же HTML-странице или слое обязаны быть промаркированы. Если Вы используете слои, Вы может иметь как маркированные, так и немаркированные скрипты, если храните их в разных слоях. Дополнительно см. "Использование Маркированных Скриптов".
    Вы можете маркировать JavaScript-файлы (доступ к которым выполняется через атрибут SRC тэга SCRIPT), инлайн-скрипты, скрипты обработчиков событий и объекты/entities JavaScript. Вы не можете маркировать URL'ы javascript:. До того как маркировать скрипт, убедитесь, что Вы его идентифицировали соответствующим образом, как описано в разделе "Идентифицирование Маркированных Скриптов".

    Минимизация Trusted Code Base

    Минимизация Trusted Code Base

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

    TCB в этом примере это весь скрипт, поскольку выданы в начале и нигде не отменяются. Вы можете уменьшить TCB, переписав программу так:

    После этого TCB - это только цикл, содержащий доступ к свойству history. Вы можете исключить излишние вызовы Java, изменяя привилегию с помощью ввода функции:

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

    Написание скрипта

    Написание скрипта

    В этом разделе специально рассматривается с написание маркированных скриптов. Дополнительно см. статьи View Source, Applying Signed Scripts.

    Ошибки в Java-Консоли

    Ошибки в Java-Консоли

    Проверьте консоль Java на наличие ошибок, если Ваши маркированные скрипты работают не так, как Вы ожидали. Вы можете увидеть такие ошибки:
    # Error: Invalid Hash of this JAR entry (-7882)
    # jar file: C:\Program Files\Netscape\Users\norris\cache\MVI9CF1F.JAR
    # path: 1
    Значение path, выведенное для маркированного JavaScript, это либо значение атрибута ID или SRC тэга, предоставляющего скрипт.

    Отладка ошибок хэша

    Отладка ошибок хэша

    Ошибки хэша возникают, если скрипт изменяется после маркировки. Чаще всего причиной этого является то, что скрипты перемещаются с одной платформы на другую в текстовом режиме, а не в бинарном. Поскольку символы разделения строк отличаются на многих платформах, хэш может измениться, если скрипт был маркирован.
    Хорошим способом решить эту проблему является использование опции -s для signPages, которая сохраняет инлайн-скрипты в JAR-файле. Вы можете затем распаковать jar-файл, если получаете ошибки хэша и сравнить его с HTML-файлом для поиска источника проблемы. О signPages, см. Signing Software with Netscape Signing Tool 1.1.

    Политика Одного Источника

    Политика одного источника работает так: при загрузке документа из одного источника, скрипт, загруженный из другого источника, не может получить или установить конкретные свойства конкретного браузера и объектов HTML в окне или фрэйме (см. Таблицу 14.2).
    Для обеспечения безопасности, JavaScript определяет источник как подстроку URL, которая содержит protocol://host, где host содержит не обязательный :port. Для иллюстрации, в следующей таблице даны примеры сравнения источника с URL http://company.com/dir/page.html.

    После маркировки

    После маркировки

    Если Вы промаркировали скрипт, а затем изменяете его, Вы обязаны повторно маркировать его. Для JavaScript-файлов это означает, что Вы не можете ничего изменять в файле. Для инлайн-скриптов - Вы не можете изменять ничего между тэгами . Для обработчиков событий и объектов JavaScript - Вы не можете изменять вообще ничего в тэге, содержащем обработчик или объект.
    Изменением может быть даже простое удаление пробела в скрипте.
    Изменения в байтовом потоке скрипта дезавуируют подпись скрипта. Сюда входит перемещение HTML-страницы между платформами, имеющими разное представление текста. Например, перемещение HTML-страницы с Windows-сервера на UNIX-сервер изменяет байтовый поток и дезавуирует подпись. (Это не влияет на просмотр страниц на разных платформах.) Чтобы избежать этого, Вы можете переместить страницу в двоичном режиме. Заметьте, что это изменяет вид страницы в Вашем текстовом редакторе, но не в браузере.
    Хотя Вы не можете вносить изменения в скрипт, Вы может изменять окружающую информацию HTML-файла. Вы можете даже копировать маркированный скрипт из одного файла в другой, если Вы гарантируете, что в скрипте ничего не меняется.

    В этом скрипте имеется кнопка,

    Пример

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

    ...


    Пример

    В это примере имеются три страницы в наборе фрэймов/frameset. Файл containerAccess.html определяет этот набор фрэймов и вызывает пользовательскую функцию, когда набор фрэймов загружен. Одна страница, secureContainer.html, содержит маркированный скрипт и экспортирует функцию. Другая страница, access.html, импортирует экспортируемую функцию и вызывает её.
    Поскольку этот пример экспортирует функцию, которая не включает или не требует расширенных привилегий, Вы можете экспортировать функцию, которая включает привилегии. Если Вы это делаете, Вы должны быть предельно осторожны, чтобы случайно не дать доступ хакеру. Дополнительно см. "Будьте Осторожны с Тем, Что Экспортируете".
    Файл containerAccess.html содержит следующий код:






    Файл secureContainer.html содержит следующий код:

    This page defines a variable and two functions.
    Only one function, publicFunction, is exported.



    Файл access.html содержит следующий код:

    This page attempts to access an exported function from a signed
    container. The access should succeed.


    Принципалы кодовой базы

    Принципалы кодовой базы

    Как и Java, JavaScript поддерживает принципалы кодовой базы/codebase principals. Принципал кодовой базы это принципал, полученный из источника скрипта, а не при проверке цифровой подписи сертификата. Поскольку принципалы кодовой базы обеспечивают слабую защиту, они по умолчанию отключены в Navigator'е.
    При публикации Ваши скрипты не должны полагаться на то, что принципалы кодовой базы включены. Вы, возможно, захотите включить принципалы кодовой базы при разработке Ваших скриптов, но Вы должны промаркировать их перед публикацией.
    Чтобы включить принципалы кодовой базы, конечные пользователи обязаны добавить соответствующую настройку в файл настроек Navigator'а. Для этого нужно добавить в файл настроек такую строку:
    user_pref("signed.applets.codebase_principal_support", true);
    Даже если принципалы кодовой базы отключены, Navigator отслеживает принципалы кодовой базы для использования при выполнении политики одного источника (см. "Политика Одного Источника"). Немаркированные скрипты имеют ассоциированный набор принципалов, куда входит один элемент - принципал кодовой базы для страницы, содержащей скрипт. Маркированные скрипты также имеют принципалы кодовой базы в дополнение к более строгим принципалам сертификата.
    Если пользователь выполняет доступ к скрипту с включёнными принципалами кодовой базы, выводится диалоговое окно, похожее на окно для маркированных скриптов. Отличие в том, что данный диалог запрашивает у пользователя предоставление привилегий на основе URL и не проверяет авторизацию доступа. Окно уведомляет пользователя, что скрипт не имеет цифровой подписи и мог быть изменён.
    ПРИМЕЧАНИЕ:
    Если страница маркированные скрипты и codebase-скрипты и поддержка принципалов кодовой базы signed.applets.codebase_principal_support включена, все скрипты на этой странице рассматриваются как немаркированные, и применяются принципалы кодовой базы.
    Дополнительно о принципалах кодовой базы см. Introduction to the Capabilities Classes.

    Проверка источника document.domain

    Проверка источника document.domain

    Имеется одно исключение из правила одного источника. Скрипт может устанавливать в значение document.domain суффикс текущего домена. Если это сделано, более краткий домен используется для последующих проверок источника. Например, скрипт в документе http://www.company.com/dir/other.html выполняет такой оператор:
    document.domain = "company.com";
    После этого страница может пройти проверку источника как http://company.com/dir/page.html.

    Проверка источника и Java-аплеты

    Проверка источника и Java-аплеты

    Ваша HTML-страница может содержать тэги APPLET для использования аплетов Java. Если тэг APPLET имеет атрибут MAYSCRIPT, этот аплет может использовать JavaScript. В это случае аплет является субъектом проверки источника при вызове JavaScript. Для этих целей источником аплета является URL документа, содержащего тэг APPLET.

    Проверка источника и слои

    Проверка источника и слои

    Слой/layer может иметь иной источник, нежели окружающий документ. Проверки источника осуществляются между документами и скриптами в слоях из различных источников. То есть, если документ содержит один или более слоёв, JavaScript проверяет источники этих слоёв, прежде чем они смогут взаимодействовать друг с другом или с документом-родителем.
    Об использовании слоёв см. Dynamic HTML in Netscape Communicator.

    Проверка источника и тэги SCRIPT, загружающие документы

    Проверка источника и тэги SCRIPT, загружающие документы

    Если Вы загружаете документ с любым URL, кроме file:, и этот документ содержит тэг
    Тогда, если JAR-файл и скрипт скопированы на другой сайт, они не будут больше работать. Если тот, кто скопировал скрипт, изменит его, чтобы обойти проверку источника скрипта, подпись дезавуируется.

    Присвоение принципалов слоям

    Рисунок 14.1 Присвоение принципалов слоям

    Присвоение принципалов слоям
    Этот метод работает так: каждый скрипт на странице рассматривается в порядке определения, javascript: URL'ы считаются новыми немаркированными скриптами.
  • Если это первый скрипт на странице, принципалы этого скрипта присваиваются окну как принципалы. (Если текущий скрипт является немаркированным, это делает принципалы окна принципалами кодовой базы.) Выполнено.

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

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

  • Иначе принципалы текущего скрипта присваиваются как принципалы контейнера. Выполнено.

  • На Рисунке 14.1 показан этот процесс.
    Например, предположим, что на странице имеются два скрипта (и нет слоёв), один скрипт маркирован, а другой - нет. Navigator сначала просматривает маркированный скрипт, что ассоциирует объект window с двумя принципалами - принципалом сертификата от маркировщика скрипта и принципалом кодовой базы, полученным из location страницы, содержащей скрипт.
    Когда Navigator видит второй (немаркированный) скрипт, он сравнивает принципалы скрипта с принципалами текущего контейнера. Немаркированный скрипт имеет только один принципал кодовой базы. При отсутствии слоёв самым внутренним контейнером является само окно, которое уже имеет принципалы.
    Поскольку наборы принципалов различны, они пересекаются, давая набор с одним членом, принципалом кодовой базы. Navigator сохраняет результат в объекте window, уменьшая его набор принципалов. Заметьте, что все функции, которые были определены в маркированном скрипте, рассматриваются теперь как немаркированные. Отсюда, смешивание маркированных и немаркированных скриптов на одной странице без слоёв приводит к тому, что все скрипты рассматриваются как непомеченные.
    Теперь предположим, что немаркированный скрипт находится в слое на странице. Это даст иное поведение. В этом случае, когда Navigator видит немаркированный скрипт, принципалы скрипта вновь сравниваются с принципалами маркированного скрипта окна и определяется, что принципалы различны. Однако теперь самый внутренний контейнер (слой) не имеет ассоциированных принципалов, немаркированные принципалы ассоциированы с самым внутренним контейнером; внешний контейнер (окно) не затрагивается. В этом случае маркированные скрипты продолжают действовать как маркированные. Однако доступ немаркированного скрипта слоя к объектам вне слоя отбрасываются, поскольку слой имеет недостаточно принципалов. См. "Изолирование Немаркированного Слоя Внутри Маркированного Контейнера".

    Скрипты, маркированные разными принципалами

    Скрипты, маркированные разными принципалами

    JavaScript отличается от Java в нескольких важных вопросах, касающихся безопасности. Java маркирует классы и может защищать внутренние методы этих классов через механизм public/private/protected. Маркировка метода как protected или private немедленно защищает его от атак извне. Кроме того, любой класс или метод, помеченный как final в Java, не может быть расширен и таким образом также защищён от вторжения.
    С другой стороны, поскольку в JavaScript нет понятия public и private-методов, отсутствуют и внутренние методы, которые могут быть защищены простой маркировкой класса. Кроме того, все методы могут изменяться на этапе прогона программы, поэтому обязаны быть защищены и на этапе прогона.
    В JavaScript Вы можете добавить новые свойства к существующим объектам или заменить существующие свойства (включая методы) на этапе прогона. Вы не может сделать это в Java. Итак, ещё раз, защита, которая автоматизирована в Java, обязана обеспечиваться в JavaScript отдельно.
    Поскольку модель маркировки скриптов в JavaScript основана на модели маркировки объектов Java, указанные отличия языков означают, что, если скрипты JavaScript произведённые разными принципалами, взаимодействуют, необходимо более надёжно защитить эти скрипты. Поскольку весь код JavaScript на одной странице HTML запускается в одном процессе, скрипты, находящиеся на одной странице могут изменять поведение друг друга. Например, скрипт может переопределить функцию, определённую в другом скрипте ранее на этой же странице.
    Чтобы обеспечить безопасность, основным положением модели безопасности маркированных скриптов в JavaScript является то, что скрипты на HTML-странице работают так, будто они все маркированы пересечением принципалов, которые маркируют каждый скрипт на этой странице.
    Например, принципалы A и B маркировали один скрипт, но только принципал A маркировал второй скрипт. В этом случае страница с обоими скриптами работает так, как если бы была маркирована только принципалом A.
    Это означает также, что, если маркированный скрипт находится на той же странице, где находится немаркированный скрипт, оба скрипта работают как немаркированные. Это происходит из-за того, что маркированный скрипт имеет принципал кодовой базы и принципал сертификата, а немаркированный скрипт имеет только принципал кодовой базы (см. "Принципалы Кодовой Базы"). Два принципала кодовой базы всегда одинаковы для скриптов на одной странице; следовательно, пересечение принципалов этих двух скриптов даст только принципал кодовой базы. Это же происходит, если оба скрипта являются немаркированными.
    Вы можете использовать функции import и export, чтобы разрешить скриптам, маркированным разными принципалами, взаимодействовать в безопасном режиме. О том, как это сделать, см. "Функции Импорта и Экспорта".

    SSL-серверы и немаркированные скрипты

    SSL-серверы и немаркированные скрипты

    Альтернативой маркировке Ваших скриптов утилитой Netscape Signing Tool является обслуживание их сервером безопасности/secure server. Navigator рассматривает все страницы, обслуживаемые SSL-сервером, как если бы они были маркированы ключом public такого сервера. В этом случае Вам не нужно маркировать отдельные скрипты.
    Если Вы имеете SSL-сервер, то Вам будет намного проще организовать работу Ваших скриптов как маркированных. Это особенно актуально, если Вы динамически генерируете скрипты на Вашем сервере и хотите, чтобы они работали как маркированные.
    О настройке Netscape-сервера как SSL-сервера см. Managing Netscape Servers.

    Сравнения источника с http://company.com/dir/page.html

    Таблица 14.1 Сравнения источника с http://company.com/dir/page.html


    URL
    РезультатПричина
    http://company.com/dir2/other.htmlУспешно
    http://company.com/dir/inner/another.htmlУспешно
    http://www.company.com/dir/other.htmlНеудачноРазные домены
    file://D|/myPage.htmНеудачноРазные протоколы
    http://company.com:80/dir/etc.htmlНеудачноРазные порты

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

    Свойства - субъекты проверки источника

    Таблица 14.2 Свойства - субъекты проверки источника


    Объект
    Свойства - субъекты проверки
    documentДля чтения и записи: anchors, applets, cookie, domain, embeds, forms, lastModified, length, links, referrer, title, URL, formName (для каждой именованной формы), reflectedJavaClass (для каждого Java-класса, отражённого в JavaScript через LiveConnect).
    Только для записи: все другие свойства.
    formelements
    imagelowsrc, src
    layersrc
    locationВсе, за исключением x и y.
    windowfind


    Свойства, разрушаемые по умолчанию

    Таблица 14.3 Свойства, разрушаемые по умолчанию


    Объект
    Разрушенное свойство
    documentcookie, domain, forms, lastModified, links, referrer, title, URL
    Formaction, name
    любой элемент ввода на формеchecked, defaultChecked, defaultValue, name, selectedIndex, selected, toString, text, value
    historycurrent, next, previous, toString
    imagename
    OptiondefaultSelected, selected, text, value
    location и Linkhash, host, hostname, href, pathname, port, protocol, search, toString
    Pluginname
    windowdefaultStatus, name, status

    Вы можете использовать элементы с разрушаемыми данными любым способом в Вашем скрипте, но, если Ваш скрипт попытается передать значение разрушенного элемента
    или любые полученные от него данные по сети любым способом (например, при отправке формы или через URL), будет выведено диалоговое окно, чтобы пользователь мог подтвердить или отменить операцию.
    Значения, полученные от элемента с разрушенными данными, также разрушены. Если разрушенное значение передаётся функции, return-значение функции разрушается. Если разрушается строка, любые подстроки строки также разрушаются. Если скрипт проверяет разрушенное значение в операторах if, for или while, скрипт сам аккумулирует разрушение.
    Вы можете включать и отключать разрушение свойств, переменных, функций и объектов, как описано в разделе "Включение и Отключение Разрушения Отдельных Элементов Данных". Вы не можете отключить разрушение свойств или элементов данных другого сервера.

    Включение и отключение разрушения отдельных элементов данных

    Включение и отключение разрушения отдельных элементов данных

    Вы можете разрушать элементы данных (свойства, переменные, функции, объекты) в Ваших скриптах для предотвращения возвращения значений, которые могут использоваться ненадлежащим образом другими скриптами или публиковаться в рамках другого скрипта. Вам может понадобиться отключить разрушение элементов данных, чтобы другие скрипты могли работать с ними. Вы не можете отключить разрушение данных элементов данных другого сервера.
    Вы управляете разрушением элементов данных с помощью двух функций: taint добавляет разрушение данных к элементу, а untaint отключает разрушение данных в элементе данных. Каждая из этих функций принимает в качестве аргумента единственный элемент данных.
    Например, следующий оператор удаляет разрушение со свойства, чтобы скрипт мог отправлять его другому серверу:
    untaintedStat=untaint(window.defaultStatus)
    // untaintedStat может теперь высылаться по URL или методом form post других скриптов
    Ни taint, ни untaint не модифицируют свой аргумент; обе функции возвращают маркированную или немаркированную ссылку на объект argument или копию значения примитивного типа (number или boolean). Эта маркировка называется taint code\код разрушения. JavaScript присваивает уникальный taint code каждому элементу данных сервера. Неразрушенные данные имеют код разрушения identity (null).
    См. taint и untaint в книге Клиентский JavaScript.
    Справочник.

    Включение разрушения

    Включение разрушения

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

  • В Unix используется команда setenv в csh.

  • В Windows используется set в файле autoexec.bat или установки пользователя NT.

  • В Macintosh редактируется источник типа "Envi" номер 128 в приложении Netscape путём удаления двух ASCII-слэшей "//" перед текстом NS_ENABLE_TAINT в конце источника.

  • NS_ENABLE_TAINT может иметь любое значение; "1" подойдёт.
    Если конечный пользователь не включил разрушение и скрипт пытается получить доступ к свойствам окна на другом сервере, будет выведено сообщение, указывающее, что доступ не разрешён.
    Чтобы определить, включено разрушение или нет, используйте метод taintEnabled. Следующий код выполняет function1, если разрушение данных/tainting включено; иначе выполняется function2.
    if (navigator.taintEnabled()) {
    function1()
    }
    else function2()
    См. taintEnabled в книге
    Клиентский JavaScript. Справочник.

    Возможности JavaScript, требующие наличия привилегий

    Возможности JavaScript, требующие наличия привилегий

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

  • Отправка формы по URL mailto: или news: требует привилегии UniversalSendMail.

  • Использование URL about:, отличное от about:blank, требует привилегии UniversalBrowserRead.

  • Объект event: Установка любого свойства требует привилегии UniversalBrowserWrite.

  • Событие DragDrop: Получение значения свойства data требует привилегии UniversalBrowserRead.

  • Объект history: Получение значения любого свойства требует привилегии UniversalBrowserRead.

  • Объект navigator:

  • Получение значения настройки с использованием метода preference требует привилегии UniversalPreferencesRead.

  • Установка значения настройки с использованием метода preference требует привилегии UniversalPreferencesWrite.

  • Объект window: Разрешение на выполнение следующих операций требует привилегии UniversalBrowserWrite.

  • Добавление и удаление directory bar, location bar, menu bar, personal bar, scroll bar, status bar или toolbar.
  • Использование методов из следующей таблицы при указанных обстоятельствах:


  • enableExternalCaptureДля захвата событий на страницах, загруженных с других серверов. Затем используйте captureEvents.
    closeБезусловное закрытие окна браузера.
    moveByПеремещение окна за пределы экрана.
    moveToПеремещение окна за пределы экрана.
    open

  • Для создания окна размером меньше 100 x 100 пикселов или больше, чем экран может вместить, с использованием innerWidth, innerHeight, outerWidth и outerHeight.

  • Для перемещения окна за пределы экрана с использованием screenX и screenY.

  • Для создания окна без строки заголовка с использованием titlebar.

  • При использования alwaysRaised, alwaysLowered или z-lock для любых установок.
  • resizeToДля изменения размеров окна на меньшие, чем 100 x 100 пикселов, или на большие, чем экран может вместить.
    resizeByДля изменения размеров окна на меньшие, чем 100 x 100 пикселов, или на большие, чем экран может вместить.

  • Установка следующих свойств при указанных обстоятельствах:

  • innerWidthПри установке внутренней ширины окна в размеры менее 100 x 100 или более, чем экран может вместить.
    innerHeightПри установке внутренней ширины окна в размеры менее 100 x 100 или более, чем экран может вместить.


    Захват событий из других серверов

    Захват событий из других серверов

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

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


    Клиентский JavaScript 1.3 Руководство

    Аргументы типа char

    Аргументы типа char

    Вы не можете передавать односимвольные строки в Java-метод, требующий аргумента типа char. Вы обязаны передавать в такие методы целое число, соответствующее Unicode-значению символа. Например, вот присвоение значения "H" переменной c:
    c = new java.lang.Character(72)

    Булевы

    Булевы

    Если Вы передаёте Булев тип JavaScript в качестве параметра Java-методам, Java конвертирует значения таким образом:

    Тип Java-параметра
    Правила конвертации
    booleanВсе значения конвертируются напрямую в Java-эквиваленты.
    lava.lang.Boolean
    java.lang.Object
    Создаётся новый экземпляр java.lang.Boolean. Каждый параметр создаёт новый экземпляр, а не один экземпляр, того же примитивного типа.
    java.lang.StringЗначения конвертируются в строки. Например:

  • true становится "true"
  • false становится "false"
  • byte
    char
    double
    float
    int
    long
    short

  • true становится 1
  • false становится 0

  • Если JavaScript Boolean передаётся в качестве параметра Java-методу, который ожидает экземпляр java.lang.String, Boolean конвертируется в строку. Используйте операцию == для сравнения результата конвертации с другими строковыми значениями.

    Числа

    Числа

    Если Вы передаёте числовые типы JavaScript в качестве параметров Java-методам, Java конвертирует значения таким образом:
    Тип Java-парамераПравила конвертации
    doubleТочное значение переносится в Java без округления и потери точности или знака.
    lava.lang.Double
    java.lang.Object
    Создаётся новый java.lang.Double -экземпляр, точное значение переносится в Java без округления и потери точности или знака.
    float

  • Значения округляются до float-точности.

  • Значения, которые слишком велики или малы, округляются до +infinity или -infinity.
  • byte
    char
    int
    long
    short

  • Значения округляются с использованием режима round-to-negative-infinity.

  • Значения, которые слишком велики или малы, дают ошибку времени выполнения.

  • NaN-значения конвертируются в 0.
  • java.lang.StringЗначения конвертируются в строки. Например,
  • 237 становится "237"
  • boolean

  • Значения 0 и NaN конвертируются в false.
  • Другие значения конвертируются в true.

  • Если JavaScript-число передаётся как параметр в Java-метод, ожидающий экземпляр java.lang.String, число конвертируется в строку. Используйте операцию == для сравнения результата конвертации с другими строковыми значениями.

    Что такое LiveConnect?

    В браузере Navigator LiveConnect даёт возможность использовать:

  • JavaScript для прямого доступа к переменным, методам, классам и пакетам Java.

  • Управлять Java-аплетами и plug-in'ами с помощью JavaScript.

  • Код Java для доступа к методам и свойствам JavaScript.


  • Доступ к JavaScript с помощью JSObject

    Доступ к JavaScript с помощью JSObject

    Например, Вы работаете с Java-классом JavaDog. Как показано в следующем коде, конструктор JavaDog принимает в качестве параметра JavaScript-объект jsDog, который определён как имеющий тип JSObject:
    import netscape.javascript.*;

    public class JavaDog
    {
    public String dogBreed;
    public String dogColor;
    public String dogSex;

    // определяется конструктор класса
    public JavaDog(JSObject jsDog)
    {
    // здесь используйте try...catch для обработки JSException
    this.dogBreed = (String)jsDog.getMember("breed");
    this.dogColor = (String)jsDog.getMember("color");
    this.dogSex = (String)jsDog.getMember("sex");
    }
    }
    Обратите внимание, что метод getMember из JSObject используется для доступа к свойствам JavaScript-объекта. Предыдущий пример использует getMember для присвоения значения JavaScript-свойства jsDog.breed Java-члену данных JavaDog.dogBreed.
    ПРИМЕЧАНИЕ:
    Лучше было бы поместить вызов getMember в блоке try...catch для отлова ошибок типа JSException. См. "Обработка Исключений JavaScript в Java".
    Чтобы лучше представить работу getMember, посмотрим на определение специального JavaScript-объекта Dog:
    function Dog(breed,color,sex) {
    this.breed = breed
    this.color = color
    this.sex = sex
    }
    Вы можете создать в JavaScript Dog-экземпляр gabby:
    gabby = new Dog("lab","chocolate","female")
    При вычислении gabby.color Вы увидите, что оно имеет значение "chocolate". Теперь, предположим, Вы создаёте JavaDog-экземпляр в Вашем JavaScript-коде, передавая объект gabby конструктору:
    javaDog = new Packages.JavaDog(gabby)
    Если Вы вычисляете javaDog.dogColor, Вы увидите, что оно также имеет значение "chocolate", поскольку метод getMember Java-конструктора присваивает свойству dogColor значение gabby.color.

    Доступ к клиентскому JavaScript

    Доступ к клиентскому JavaScript

    Давайте теперь отдельно рассмотрим использование Java для доступа к клиентскому JavaScript. Автор HTML-страницы обязан разрешить аплету доступ к JavaScript, специфицировав атрибут MAYSCRIPT тэга . Это предотвращает доступ аплета к JavaScript на странице без ведома автора страницы. Попытка получить доступ к JavaScript из аплета, не имеющего атрибут MAYSCRIPT, генерирует исключение. Тэг MAYSCRIPT нужен только для доступа Java к JavaScript; он не требуется для доступа JavaScript к Java.

    Доступ к объектам и свойствам JavaScript

    Доступ к объектам и свойствам JavaScript

    Метод getMember класса netscape.javascript.JSObject даёт доступ к объектам и свойствам JavaScript. Вызывайте getWindow для получения дескриптора окна JavaScript, затем вызывайте getMember для доступа к каждому JavaScript-объекту. Заметьте, что JavaScript-объекты появляются в Java как экземпляры класса netscape.javascript.JSObject.
    Например, следующий код Java даёт доступ к JavaScript-объекту document.testForm через переменную myForm:
    public void init() {
    win = JSObject.getWindow(this);
    myForm=win.eval("document.testForm")
    }
    Вы могли бы использовать следующие строки вместо myForm=win.eval("document.testForm"):
    JSObject doc = (JSObject) win.getMember("document");
    JSObject myForm = (JSObject) doc.getMember("testForm");
    Если JavaScript-объект document.testForm.jazz это переключатель/checkbox, следующий код Java даёт доступ к его свойству checked:
    public void init() {
    win = JSObject.getWindow(this);
    JSObject doc = (JSObject) win.getMember("document");
    JSObject myForm = (JSObject) doc.getMember("testForm");
    JSObject check = (JSObject) myForm.getMember("jazz");
    Boolean isChecked = (Boolean) check.getMember("checked");
    }

    Другие объекты JavaScript

    Другие объекты JavaScript

    Если Вы передаёте любой другой объект JavaScript в качестве параметра Java-методу, Java конвертирует этот объект в соответствии со следующими правилами:
    Тип Java-параметра Правила конвертации
    java.lang.JSObject
    java.lang.Object
    Объект оборачивается в новый экземпляр java.lang.JSObject.
    java.lang.StringОболочка с объекта снимается, вызывается метод toString развёрнутого Java-объекта, результат возвращается как новый экземпляр java.lang.String.
    byte
    char
    double
    float
    int
    long
    short
    Объект конвертируется в значение с использованием логики оператора ToPrimitive, описанного в ECMA-262. Подсказка PreferredType, используемая с этим оператором, это Number.
    booleanОболочка с объекта снимается и возникает одна из следующих ситуаций:

  • Если объект null, он конвертируется в false.

  • Если объект имеет какое-нибудь другое значение, он конвертируется в true.

  • В JavaScript 1.2 и ранее - оболочка с объекта снимается, и возникает одна из следующих ситуаций:

  • Если развёрнутый объект имеет метод booleanValue, исходный объект конвертируется в return-значение.

  • Если развёрнутый объект не имеет метода booleanValue, конвертация терпит неудачу.


  • Использование классов LiveConnect

    Использование классов LiveConnect

    Все JavaScript-объекты появляются в коде Java как экземпляры netscape.javascript.JSObject. Когда Вы вызываете метод в Вашем Java-коде, Вы можете передать ему JavaScript-объект в качестве одного из аргументов. Для этого Вы обязаны определить соответствующий формальный параметр метода как имеющего тип JSObject.
    Также всегда при использовании JavaScript-объектов в Вашем Java-коде, Вы должны помещать вызов JavaScript-оъекта внутри блока операторов try...catch, который обрабатывает ошибки типа netscape.javascript.JSException. Это даёт Java-коду возможность обрабатывать ошибки выполнения кода JavaScript, которые появляются в Java как исключения типа JSException.

    JavaClass-объекты

    JavaClass-объекты

    Если Вы передаёте JavaScript JavaClass-объект как параметр Java-методу, Java конвертирует этот объект в соответствии со следующими правилами:
    Тип Java-параметра Правила конвертации
    java.lang.ClassОболочка с объекта снимается.
    java.lang.JSObject
    java.lang.Object
    Объект JavaClass оборачивается в новый экземпляр java.lang.JSObject.
    java.lang.StringОболочка с объекта снимается, вызывается метод toString развёрнутого Java-объекта, результат возвращается как новый экземпляр java.lang.String.
    booleanОболочка с объекта снимается и возникает одна из следующих ситуаций:

  • Если объект null, он конвертируется в false.

  • Если объект имеет какое-нибудь другое значение, он конвертируется в true.

  • В JavaScript 1.2 и ранее - оболочка с объекта снимается, и возникает одна из следующих ситуаций:
  • Если развёрнутый объект имеет метод booleanValue, исходный объект конвертируется в return-значение.
  • Если развёрнутый объект не имеет метода booleanValue, конвертация терпит неудачу.


  • Консоль Java

    Консоль Java это окно Navigator'а отображающее сообщения Java. Если Вы используете переменные классов out или err в java.lang.System для вывода сообщения, сообщение появляется на консоли. Для показа Java-консоли, выберите Java Console в меню Communicator.
    Вы можете использовать Java-консоль для показа сообщений пользователю или для трассировки значений переменных в различных точках при выполнении программы. Учтите, что многие пользователи отключают показ консоли.
    Например, следующий код Java выводит сообщение "Hello, world!" в Java-консоль:
    public void init() {
    System.out.println("Hello, world!")
    }

    Конвертация JavaScript в Java

    Конвертация JavaScript в Java

    Если Вы вызываете Java-метод и передаёте ему параметры из JavaScript, тип передаваемых параметров конвертируется в соответствии с правилами, описанными в следующих разделах:
  • Числа

  • Булевы
  • Строки

  • Undefined-значения
  • Null-значения

  • Объекты JavaArray и JavaObject
  • JavaClass-объекты

  • Другие объекты JavaScript

  • Return-значения методов netscape.javascript.JSObject всегда конвертируются в экземпляры java.lang.Object. Правила конвертации этих return-значений также описаны в этих разделах.
    Например, если JSObject.eval возвращает JavaScript-число, Вы можете найти правило конвертации этого числа в экземпляр java.lang.Object в разделе "Числа".


    Поскольку Java является строго типизированным языком, а JavaScript типизирован слабо, машина выполнения JavaScript конвертирует значения аргументов в подходящие типы данных других языков, когда Вы используете LiveConnect. Эта конвертация рассматривается в следующих разделах:
  • Конвертация JavaScript в Java

  • Конвертация Java в JavaScript


  • Null-значения

    Null-значения

    Если Вы передаёте null-значения JavaScript в качестве параметров Java-методам, Java конвертирует значения так:
    Тип Java-параметраПравила конвертации
    Любой класс
    Интерфейс любого типа
    Значение становится null.
    byte
    char
    double
    float
    int
    long
    short
    Значение становится 0.
    booleanЗначение становится false.


    Объект Packages

    Объект 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")

    Объекты JavaArray и JavaObject

    Объекты JavaArray и JavaObject

    В большинстве случаев, если Вы передаёте JavaScript JavaArray или JavaObject в качестве параметров Java-методу, Java просто снимает оболочку с объекта; иногда объект приводится к другому типу данных в соответствии с правила из таблицы:
    Тип Java-параметра
    Правила конвертации
    Любой интерфейс или класс, который совместим при присвоении с развёрнутым объектом.Оболочка с объекта снимается.
    java.lang.StringОболочка с объекта снимается, вызывается метод toString развёрнутого Java-объекта, результат возвращается как новый экземпляр java.lang.String.
    byte
    char
    double
    float
    int
    long
    short
    Оболочка с объекта снимается, и возникает одна из следующих ситуаций:

  • Если развёрнутый Java-объект имеет метод doubleValue, JavaArray или JavaObject конвертируется в значение, возвращаемое этим методом.

  • Если развёрнутый Java-объект не имеет метода doubleValue, возникает ошибка.
  • booleanОболочка с объекта снимается, и возникает одна из следующих ситуаций:

  • Если объект null, он конвертируется в false.

  • Если объект имеет любое другое значение, он конвертируется в true.

  • В JavaScript 1.2 и ранее - оболочка с объекта снимается, и возникает одна из следующих ситуаций:

  • Если развёрнутый объект имеет метод booleanValue, исходный объект конвертируется в return-значение.

  • Если развёрнутый объект не имеет метода booleanValue, конвертация терпит неудачу.

  • Интерфейс или класс совместимы при присвоении, если развёрнутый объект является экземпляром типа Java-параметра. То есть следующий оператор обязан возвратить true:
    unwrappedObject instanceof parameterType

    Обработка исключений JavaScript в Java

    Обработка исключений JavaScript в Java

    Если код JavaScript, вызванный из Java, терпит неудачу на этапе прогона, он вызывает исключение. Если Вы вызываете JavaScript-код из Java, Вы можете отловить это исключение в блоке операторов try...catch. Исключение JavaScript доступно Вашему Java-коду как экземпляр netscape.javascript.JSException.

    JSException это Java-оболочка вокруг исключения любого типа, вызванного JavaScript, аналогично тому, как JSObject-экземпляры являются оболочками для JavaScript-объектов.
    Используйте JSException при вычислении JavaScript-кода в Java. Если JavaScript-код не вычисляется из-за ошибки компиляции JavaScript или какой-нибудь другой ошибки времени выполнения, интерпретатор JavaScript генерирует сообщение об ошибке, которое конвертируется в JSException-экземпляр.
    Например, Вы можете использовать try...catch для обработки исключений LiveConnect:
    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 как document.appletName, где appletName это значение атрибута NAME тэга . Массив applets также содержит все аплеты страницы; Вы можете обратиться к элементам этого массива по имени аплета (как в ассоциативном массиве) или по порядковому номеру аплета на странице (начиная с 0).
    Например, рассмотрим аплет "Hello World" на языке Java:
    import java.applet.Applet;
    import java.awt.Graphics;public class HelloWorld extends Applet {
    public void paint(Graphics g) {
    g.drawString("Hello world!", 50, 25);
    }
    }
    Следующий HTML запускает и отображает аплет и именует его "HelloWorld" (в атрибуте NAME):


    Если это первый аплет документа (самый верхний на странице), Вы можете обратиться к нему в JavaScript одним из следующих способов:
    document.HelloWorld
    document.applets["HelloWorld"]
    document.applets[0]
    Массив applets имеет свойство length, document.applets.length, указывающее количество аплетов в документе.
    Все public-переменные, объявленные в аплете и его классах и пакетах-предках, доступны в JavaScript. Static-методы и свойства, объявленные в аплете, доступны в JavaScript как методы и свойства объекта Applet. Вы можете получать и устанавливать значения свойств и вызывать методы, возвращающие строковые, числовые и Булевы значения.

    Получение дескриптора для окна JavaScript

    Получение дескриптора для окна JavaScript

    Прежде чем Вы получите доступ к JavaScript в Navigator'е, Вы обязаны получить дескриптор/handle для окна Navigator'а. Используйте метод getWindow класса netscape.javascript.JSObject для получения дескриптора окна, передавая его объекту Applet.
    Например, если win это ранее объявленная переменная типа JSObject, следующий Java-код присваивает дескриптор окна переменной win:
    public class myApplet extends Applet {
    public void init() {
    JSObject win = JSObject.getWindow(this);
    }
    }

    Hello World

    Пример 1: Hello World

    Например, Вы можете изменить вышеприведённый аплет HelloWorld:

  • переопределить его метод init, чтобы он объявлял и инициализировал строку myString

  • определить метод setString, принимающий строковой аргумент, присвоить этот аргумент объекту myString и вызвать метод repaint. (Методы paint и repaint наследуются из java.awt.Component).

  • Исходный код Java выглядит теперь так:
    import java.applet.Applet;
    import java.awt.Graphics;public class HelloWorld extends Applet {
    String myString; public void init() {
    myString = new String("Hello, world!");
    }
    public void paint(Graphics g) {
    g.drawString(myString, 25, 20);
    }
    public void setString(String aString) {
    myString = aString;
    repaint();
    }
    }
    Сделав стоку сообщения переменной, Вы можете модифицировать её из JavaScript. Теперь изменим HTML-файл:

  • добавим форму с текстовым полем и кнопкой и

  • создадим для кнопки обработчик onClick, вызывающий метод setString из HelloWorld со строкой из текстового поля в качестве аргумента.

  • Файл HTML выглядит так:


    onClick="document.HelloWorld.setString(document.form1.str.value)">



    Когда Вы компилируете аплет HelloWorld и загружаете HTML-страницу в Navigator, Вы сначала увидите "Hello, World!", выведенное на серой панели аплета. Однако Вы можете теперь изменить текст, введя новый в текстовом поле и щёлкнув кнопку. Это демонстрирует управление аплетом из JavaScript.

    аплет Flashing Color Text

    Пример 2: аплет Flashing Color Text

    Более сложный пример - аплет, отображающий "вспыхивающий" текст разными цветами. Текстовое поле и кнопка позволяют ввести новый текст. Этот аплет показан на Рисунке 15.1.

    Hello World

    Пример: Hello World

    Вернёмся к примеру HelloWorld, изменим метод paint в коде Java таким образом, чтобы он вызывал JavaScript-метод alert (с сообщением "Painting!"):
    public void paint(Graphics g) {
    g.drawString(myString, 25, 20);
    JSObject win = JSObject.getWindow(this);
    String args[] = {"Painting!"};
    win.call("alert", args);
    }
    Затем добавим атрибут MAYSCRIPT в тэг на HTML-странице, рекомпилируем аплет и запустим его. При каждой прорисовке аплета (когда он инициализируется, когда Вы вводите новое текстовое значение и когда страница перезагружается) выводится JavaScript-бокс alert. Это простая иллюстрация вызова JavaScript из Java.
    Можно добиться того же эффекта таким образом:
    public void paint(Graphics g) {
    g.drawString(myString, 25, 20);
    JSObject win = JSObject.getWindow(this);
    win.eval("alert('Painting')");
    }
    ПРИМЕЧАНИЕ:
    Может понадобиться перезагрузка HTML-страницы путём выбора Open Page в меню File вместо щелчка по кнопке Reload, чтобы гарантировать реинициализацию аплета.

    Работа с массивами Java

    Работа с массивами Java

    Если какой-нибудь Java-метод создаёт массив и Вы обращаетесь к этому массиву в JavaScript, Вы работаете с JavaArray. Например, следующий код создаёт JavaArray x из 10 элементов типа int:
    theInt = java.lang.Class.forName("java.lang.Integer")
    x = java.lang.reflect.Array.newInstance(theInt, 10)
    Подобно JavaScript-объекту Array, JavaArray имеет свойство length, которое возвращает количество элементов массива. В отличие от Array.length, JavaArray.length является свойством только для чтения, так как количество элементов в Java-массиве фиксируется в момент создания.

    Работа с оболочками

    В JavaScript оболочка\wrapper это объект типа данных целевого языка, который содержит объект исходного языка. На стороне JavaScript Вы можете использовать объект-оболочку для доступа в методам и полям Java-объекта; вызов метода или доступ к свойству в оболочке приводит к вызову Java-объекта. На стороне Java - JavaScript-объекты оборачиваются в экземпляры класса netscape.javascript.JSObject и передаются в Java.
    Если JavaScript-объект пересылается в Java, машина выполнения создаёт Java-оболочку типа JSObject; когда JSObject высылается из Java в JavaScript, машина выполнения развёртывает его в оригинальный тип JavaScript-объекта. Класс JSObject предоставляет интерфейс для вызова методов JavaScript и проверки свойств JavaScript.

    Аплет Flashing text

    Рисунок 15.1 Аплет Flashing text


    Аплет Flashing text

    Вот исходный HTML:


    Enter new text for the flashing display: NAME="textBox"
    LENGTH=50>Click the button to change the display:
    VALUE="Change Text"
    onClick="document.colorApp.setString(document.colorText.textBox.value)">

    Этот аплет использует public-метод setString для специфицирования вспыхивающего текста. В HTML-форме обработчик onClick кнопки позволяет менять строку "Hello, world!" через вызов метода setString.
    Здесь colorText это имя HTML-формы и textBox - имя текстового поля. Обработчик события передаёт значение, которое пользователь ввёл в текстовое поле, методу setString Java-аплета.

    Ссылки на пакет и класс

    Ссылки на пакет и класс

    Простые ссылки из JavaScript на пакеты и классы Java создают объекты JavaPackage и JavaClass. Ранее в примере о компании Redwood, например, ссылка Packages.redwood это объект JavaPackage. Аналогично, ссылка java.lang.String это JavaClass-объект.
    В большинстве случаев Вам не нужно беспокоиться о создании объектов JavaPackage и JavaClass - Вы просто работаете с пакетами и классами Java, а LiveConnect прозрачно создаёт эти объекты.
    JavaClass-объекты не конвертируются автоматически в экземпляры java.lang.Class, когда Вы передаёте их как параметры Java-методам - Вы обязаны создавать оболочку для java.lang.Class-экземпляра. В следующем примере метод forName создаёт объект-оболочку theClass, который затем передаётся методу newInstance для создания массива.
    theClass = java.lang.Class.forName("java.lang.String")
    theArray = java.lang.reflect.Array.newInstance(theClass, 5)

    Строковые

    Строковые

    Если Вы передаёте строковые значения JavaScript в качестве параметров Java-методам, Java конвертирует значения так:
    Тип Java-параметраПравила конвертации>
    lava.lang.String
    java.lang.Object
    Строка JavaScript конвертируется в экземпляр java.lang.String с ASCII-значением.
    byte
    double
    float
    int
    long
    short
    Все значения конвертируются в числа, как описано в спецификации ECMA-262.
    charВсе значения конвертируются в числа.
    boolean

  • Пустая строка становится false.
  • Все другие значения становятся true.


  • Объекты LiveConnect

    Таблица 15.1 Объекты LiveConnect

    ОбъектОписание
    JavaArrayОбёрнутый Java-массив, доступ к которому выполняется из кода JavaScript.
    JavaClassСсылка JavaScript на Java-класс.
    JavaObjectОбёрнутый объект Java, доступ к которому выполняется из кода JavaScript.
    JavaPackageСсылка JavaScript на Java-пакет.

    ПРИМЕЧАНИЕ:
    Поскольку Java является строго типизированным языком, а JavaScript типизирован слабо, машина выполнения JavaScript конвертирует значения аргументов в подходящие типы данных других языков, когда Вы используете LiveConnect. См. полную информацию в разделе "Конвертация Типов Данных".
    Существование объектов LiveConnect в некотором смысле прозрачно, так как Вы взаимодействуете с Java в довольно интуитивной манере. Например, Вы можете создать Java-объект String и присвоить его JavaScript-переменной myString путём использования операции new с Java-конструктором:
    var myString = new java.lang.String("Hello world")
    В предыдущем примере переменная myString это JavaObject, потому что она содержит экземпляр Java-объекта String. Как JavaObject, myString имеет доступ к public-методам экземпляра java.lang.String и его суперкласса, java.lang.Object. Эти Java-методы доступны в JavaScript как методы из JavaObject, и Вы можете вызвать их так:
    myString.length() // возвращает 11

    Undefined-значения

    Undefined-значения

    Если Вы передаёте undefined-значения JavaScript в качестве параметров Java-методам, Java конвертирует значения так:
    Тип Java-параметра Правила конвертации
    lava.lang.String
    java.lang.Object
    Значение конвертируется в экземпляр java.lang.String, значением которого становится строка "undefined".
    booleanЗначение становится false.
    double
    float
    Значение становится NaN.
    byte
    char
    int
    long
    short
    Значение становится 0.

    Конвертация undefined-значений возможна только в JavaScript 1.3. Предыдущие версии JavaScript не поддерживают значение undefined.
    Если JavaScript-значение undefined передаётся в качестве параметра Java-методу, который ожидает экземпляр java.lang.String, значение undefined конвертируется в строку. Используйте операцию == для сравнения результата конвертации с другими строковыми значениями.

    Управление Java Plug-in'ами

    Управление Java Plug-in'ами

    Каждый plug-in документа отражается в JavaScript как элемент массива embeds. Например, следующий HTML-код включает AVI plug-in в документ:

    Если это первый plug-in в документе, Вы может получить к нему доступ одним из следующих способов:
    document.embeds[0]
    document.embeds["myEmbed"]
    document.myEmbed
    Если plug-in ассоциирован с Java-классом netscape.plugin.Plugin, Вы можете получить доступ к его static-переменным и методам тем способом, которым Вы получаете доступ к переменным и методам.
    Массив embeds имеет свойство length, document.embeds.length, указывающего количество plug-in'ов, встроенных в документ.
    Книга Plug-in Guide содержит информацию о:

  • вызове Java-методов из plug-in'ов
  • вызове методов plug-in'а из Java


  • Управления Java-аплетами

    Управления Java-аплетами

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

    Включение LiveConnect

    Служба LiveConnect по умолчанию включена в Navigator'е 1.1 и последующих версиях. Чтобы LiveConnect работала, должны быть включены Java и JavaScript. Для проверки этого выберите Preferences в меню Edit и просмотрите раздел Advanced.
  • Убедитесь, что опция Enable Java отмечена.

  • Убедитесь, что опция Enable JavaScript отмечена.

  • Для отключения Java или JavaScript уберите галочки в переключателях; если Вы это сделали, LiveConnect работать не будет.

    Вызов методов JavaScript

    Вызов методов JavaScript

    Метод eval класса netscape.javascript.JSObject позволяет вычислять произвольные выражения JavaScript. Используйте метод getWindow для получения дескриптора окна JavaScript, затем используйте eval для доступа к JavaScript-методу.
    Вот синтаксис вызова методов JavaScript:
    JSObject.getWindow().eval("expression")
    expression это JavaScript-выражение, которое вычисляется в вызов JavaScript-метода.
    Например, следующий код Java использует eval для вызова JavaScript-метода alert, если возникает событие MouseUp:
    public void init() {
    JSObject win = JSObject.getWindow(this);
    }public boolean mouseUp(Event e, int x, int y) {
    win.eval("alert(\"Hello world!\");");
    return true;
    }
    По-другому можно вызвать JavaScript-методы JSObject-методом call. Используйте следующий вызов JavaScript-метода из Java, кода Вы хотите передать Java-объекты в качестве аргументов:
    JSObject.call(methodName, argArray)
    где argArray это массив Java-объектов, используемый для передачи аргументов JavaScript-методу.
    Если Вы хотите передать примитивные значения JavaScript-методу, Вы обязаны использовать Java-оболочки объектов (такие как Integer, Float и Boolean), а затем наполнить Array такими объектами.

    Вызов пользовательский функций

    Вызов пользовательский функций

    Вы можете также вызвать определённые пользователем функции из Java-аплета. Например, добавьте следующую функцию в HTML-страницы с аплетом HelloWorld:

    Эта простая функция выведет диалог alert, содержащий имя и версию используемого клиентского программного обеспечения. Затем измените метод init в Вашем Java-коде аналогично тому, как Вы изменили paint:
    public void init() {
    myString = new String("Hello, world!")
    JSObject win = JSObject.getWindow(this)
    String args2[] = {""}
    win.call("test", args2)
    }
    Заметьте, что args2 объявлен как массив без элементов, хотя этот метод не принимает аргументов. Когда Вы рекомпилируете аплет и перезагрузите HTML-страницу (и реинициализируете аплет), JavaScript-диалог alert выведет версию Navigator'а, который запущен у Вас. Это простая иллюстрация вызова пользовательской функции из Java.

    Взаимодействие Java и JavaScript

    Если Вы хотите использовать объекты JavaScript в Java, Вы обязаны импортировать пакет netscape.javascript в Ваш Java-файл. Этот пакет определяет следующие классы:

  • netscape.javascript.JSObject даёт коду Java доступ к методам и свойствам JavaScript.

  • netscape.javascript.JSException позволяет Java-коду обрабатывать ошибки JavaScript.

  • netscape.plugin.Plugin даёт клиентскому JavaScript и аплетам возможность работать с plug-in'ом.

  • Начиная с JavaScript 1.2, эти классы поставляются в .jar-файле; в предыдущих версиях JavaScript эти классы находились в .zip-файле. См. также книгу
    Клиентский JavaScript. Справочник.
    Для доступа к классам LiveConnect поместите файл .jar или .zip в CLASSPATH компилятора JDK одним из следующих способов:

  • создайте переменную окружения CLASSPATH для специфицирования пути и имени .jar или .zip-файла.

  • специфицируйте размещение .jar или .zip-файла при компиляции путём использования команды -classpath в командной строке.

  • Например, в Navigator 4. 0 для Windows NT классы поставляются в файле java40.jar в директории Program\Java\Classes ниже директории Navigator'а. Вы можете специфицировать переменную окружения в Windows NT, открыв System из Control Panel и создав пользовательскую переменную окружения CLASSPATH со значением типа такого:
    D:\Navigator\Program\Java\Classes\java40.jar
    См. в документации к Sun JDK информацию о CLASSPATH.
    ПРИМЕЧАНИЕ:
    Поскольку Java является строго типизированным языком, а JavaScript типизирован слабо, машина выполнения JavaScript конвертирует значения аргументов в подходящие типы данных других языков, когда Вы используете LiveConnect. См. полную информацию в разделе "Конвертация Типов Данных".

    Взаимодействие JavaScript с Java

    Когда Вы обращаетесь к пакету или классу Java или работаете с массивом или объектом Java, Вы используете один из специальных объектов LiveConnect. Все запросы JavaScript к Java выполняются с помощью этих объектов, резюме по которым дано в таблице.

    Клиентский JavaScript 1.3 Руководство

    Фильтры новостей

    Всё сказанное выше rule-файла относится и к фильтрам новостей. Единственное отличие - в строке type. Для фильтров почты Вы используете type="2". Для фильтров новостей Вы используете type="8".

    Обращение к объекту сообщения

    Функции фильтра принимают один аргумент, объект сообщения. Для фильтров новостей это объект News Message, а для фильтров почты - объект Mail Message.

    Открытие консоли JavaScript

    Для открытия консоли JavaScript выполните одно из следующих действий. Консоль открывает новое окно.

  • Введите в адресную строку такой URL.
  • javascript:

  • Выберите Open Page из меню File и введите следующий URL:
  • javascript:

  • Вставьте следующий код в HTML Вашей страницы:
  • Open JavaScript console

    Отладка фильтров

    Если с фильтрами имеются какие-нибудь проблемы, Вы можете получить стандартное предупреждение JavaScript о природе ошибки. При наличии проблем, фильтры не используются для фильтрации сообщений. Соответственно, если проблемы имеются, вся почта в папке Inbox остаётся без изменений.

    Почтовые сообщения

    Почтовые сообщения

    Объект почтового сообщения имеет следующие методы:
    Метод
    Описание
    killThread()Помечает поток как игнорируемый.
    watchThread()Помечает поток как наблюдаемый.
    trash()Помечает сообщение как прочитанное и перемещает его в папку trash/мусор.

    Объект почтового сообщения имеет следующие свойства:
    Свойство
    Описание
    folderПапка, содержащая данное сообщение.
    readПрочитано сообщение или нет.
    priorityПриоритет сообщения.

    Для перемещения почтового сообщения Вы устанавливаете свойство folder объекта сообщения. Можно использовать полный путь или синтаксис mailbox: в URL для специфицирования папки назначения.
    Свойство priority можно устанавливать, используя целые числа или строки. Возможные значения:
  • None
  • Lowest

  • Low
  • Normal
  • High

  • Highest


  • AПочтовые Фильтры

    Приложение A
    Почтовые Фильтры

    В этом приложении показано, как применять JavaScript для фильтрации входящей почты и новостей при использовании Netscape Messenger.
    Процесс фильтрации состоит из двух этапов:

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

  • Добавить вхождения этой JavaScript-функции в файл правил/mail rules file. Ваш rules-файл может содержать несколько фильтров. Messenger применяет каждый фильтр к сообщению, пока один из них не сработает.

  • В приложении имеются следующие разделы:
  • Создание фильтра и добавление его в rules-файл

  • Фильтры новостей

  • Обращение к объекту сообщения

  • Отладка фильтров

  • Более сложный пример


  • B Отображение Ошибок с Помощью Консоли JavaScript

    Приложение B

    Отображение Ошибок с Помощью Консоли JavaScript

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

  • Открытие консоли JavaScript

  • Вычисление выражений с помощью консоли

  • Вывод сообщений об ошибках на консоль

  • JavaScript 1.2 и более ранние версии. Консоль JavaScript отсутствует.

    Шапки/Headers сообщений

    Шапки/Headers сообщений

    Помимо свойств, приведённых выше, объект почтового сообщения предоставляет все шапки /headers сообщения как свойства только для чтения. Так, тема сообщения может быть получена как message.subject, а список CC как message.cc. Шапки с дефисами в именах (как Resent-from) не могут быть получены с dot-синтаксисом. Запрашивайте их с использованием синтаксиса массива для значения свойства (как message["Resent-from"]).

    Сообщение новостей

    Сообщение новостей

    Объект сообщения новостей/News Message имеет следующие методы:

    Метод
    Описание
    killThread()Помечает поток как игнорируемый.
    watchThread()Помечает поток как наблюдаемый.

    Объект сообщения новостей имеет следующие свойства:
    Свойство
    Описание
    group(Только для чтения) Группа новостей, содержащая данное сообщение.
    readПрочитано сообщение или нет.
    sender(Только для чтения) Отправитель сообщения.
    subject(Только для чтения) Тема сообщения.


    Создание фильтра и добавление его в rules-файл

    Сначала нужно написать файл filters.js. Он содержит функции JavaScript, которые выполняют фильтрацию почты. Эти функции могут использовать все возможности клиентского JavaScript. Размещение этого файла зависит от платформы, как показано в следующей таблице.
    Платформа
    Размещение файла
    Unix$(HOME)/.netscape/filters.js
    где $(HOME) это директория, в которой установлен Navigator.
    Windows\Program Files\Communicator\Users\\Mail\filters.js
    Macintoshfilters.js в корневой директории каталога Вашего профиля.

    Вот пример простого файла фильтра. Он сохраняет все сообщения от my_mom в папке "FromMom" и помечает их как имеющие приоритет high. Он также высылает все сообщения из my_sister в папку trash.
    // файл filters.js
    function MomFilter(message) {
    if (message.from.indexOf("my_mom@mothers.net") != -1) {
    message.priority = "High";
    message.folder = "mailbox:FromMom";
    }
    else if (message.subject.indexOf("my_sister@sisters.net") != -1) {
    message.trash();
    }
    }
    ПРИМЕЧАНИЕ: Нет способа специфицировать папку IMAP через использование синтаксиса mailbox:. Поэтому, если Вы перераспределяете что-либо с использованием IMAP, всё это будет происходить на Вашей локальной машине.
    После того как функция фильтра JavaScript написана, Вы добавляете ссылку на этот фильтр в Ваш файл почтовых правил/mail rules file. Размещение rules-файла также зависит от платформы, как показано в следующей таблице.
    ПлатформаРазмещение файла
    Unix$(HOME)/.netscape/mailrule где $(HOME) это директория, в которой установлен Navigator.
    Windows\Program Files\Communicator\Users\\Mail\rules.dat
    MacintoshFilter Rules в корневой директории каталога Вашего профиля.

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

    name="filterName"
    enabled="yes"
    type="2"
    scriptName="scriptName"

    где

    name="filterName" Описательное имя фильтра.
    enabled="yes" Использовать этот фильтр. Для отключения фильтра запишите enabled="no".
    type="2" Пометить этот фильтр как фильтр JavaScript.
    scriptName="scriptName" Выполняемая функция JavaScript.
    Реальный ввод может быть таким:

    name="Filter for Mom"
    enabled="yes"
    type="2"
    scriptName="MomFilter"

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

    Если у Вас ещё нет rule-файла почты, Вы должны будете добавить две строки вверху файла (до любых ссылок на фильтры):

    version="6"
    logging="no"

    Вычисление выражений с помощью консоли

    Окно консоли JavaScript состоит из двух фрэймов. Нижний фрэйм содержит поле javascript typein, где Вы можете вводить однострочные выражения. Вы можете использовать это поле для присвоения значений переменным, тестирования операций сравнения и выполнения математических операций.
    Чтобы вычислить выражение:

  • Введите выражение в поле javascript typein.

  • Нажмите Return.

  • Результаты выводятся в верхнем фрэйме.
    Например, Вы можете вычислить следующие выражения:
    alert("hello there")// выводит диалог alert
    5-2 // выводит "3" в верхнем фрэйме
    var high=100; var low=45; // создаёт две переменные
    high-low; // выводит 55 в верхнем фрэйме

    Вывод сообщений об ошибках на консоль

    Если ошибочное условие JavaScript обнаружено в клиенте (например, на HTML-странице или в сообщении email), выводится диалоговое окно с описанием ошибки (например, Line 64: myVariable is not defined). Большинству пользователей эти сообщения ничего не говорят, и необходимость постоянно закрывать диалоговое окно начинает надоедать. Ошибки интересны только JavaScript-разработчикам, тестерам и особо утончённым пользователям.
    Вы можете форсировать отображение ошибок JavaScript только в консоли JavaScript. Тогда, при возникновении ошибки JavaScript, сообщение о ней перенаправляется на консоль, и диалоговое окно не выводится. Поскольку консоль обычно не отображается, пользователь не получает прямых указаний на возникновении ошибок JavaScript. Если пользователь или разработчик хочет просматривать сообщения об ошибках JavaScript, он должен будет открыть консоль.
    Текст сообщения об ошибке JavaScript появляется в консоли так же, как и в традиционном диалоговом окне.
    Описания ошибок JavaScript всегда выводятся на английском языке, независимо от локальных установок операционной системы.

    

        Бизнес: Предпринимательство - Малый бизнес - Управление