Клиентский JavaScript 1.3 Руководство
Что такое JavaScript?
JavaScript это разработанный корпорацией Netscape межплатформенный объектно-ориентированный язык скриптинга (сценариев). Ядро JavaScript содержит набор основных объектов, таких как Array, Date и Math, и основной набор элементов языка, таких как операции, управляющие структуры и операторы. Ядро JavaScript может быть расширено путём предоставления дополнительных объектов; например:Серверный 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
Клиентский JavaScriptWeb-браузеры, такие как 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 (адресную строку).
Язык JavaScript
Рисунок 1.1 Язык JavaScript
Следующие разделы являются введением в JavaScript на клиенте и на сервере.
Клиентский JavaScript
Рисунок 1.2 Клиентский 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 в процессе разработки
На втором этапе, показанном на Рисунке 1.4, страница приложения запрашивается клиентским браузером. Машина выполнения использует исполняемый файл приложения для поиска исходной страницы и динамически генерирует возвращаемую клиенту HTML-страницу. Машина запускает на выполнение операторы серверного JavaScript, найденные на странице. В результате этого на HTML-страницу могут быть добавлены новый HTML или операторы JavaScript. Машина выполнения высылает результирующую страницу по сети Navigator'у-клиенту, который запускает на выполнение клиентский JavaScript и выводит результаты.
Серверный JavaScript на этапе прогона
Рисунок 1.4 Серверный 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 и ECMANetscape тесно сотрудничает с ECMA для создания ECMA-спецификации. В таблице показано соотношение между версиями JavaScript и ECMA.
JavaScript в сравнении с Java
Таблица 1.1 JavaScript в сравнении с Java| Интерпретируется (не компилируется) клиентом. | Скомпилированные байт-коды загружаются с сервера, выполняются на клиенте. | ||
| Объектно-ориентированный. Нет отличий в типах объектов. Наследование идёт через механизм прототипов, а свойства и методы могут динамически добавляться к любому объекту. | На основе классов. Объекты делятся на классы и экземпляры с наследованием по всей цепи иерархии классов. Классы и экземпляры не могут иметь свойства или методы, добавляемые динамически. | ||
| Код, интегрированный с и внедрённый в HTML. | Аплеты отличаются от HTML (при доступе из HTML-страниц). | ||
| Тип данных переменной не объявляется (динамическая типизация). | Тип данных переменной обязан быть объявлен (статическая типизация). | ||
| Не может автоматически записывать на жёсткий диск. | Не может автоматически записывать на жёсткий диск. |
Об отличиях JavaScript и Java см. также Главу 8 "Объектная Модель. Детали".
Версии JavaScript и ECMA
Таблица 1.2 Версии JavaScript и ECMA| JavaScript 1.1 | ECMA-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.3 | JavaScript 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 и ISOUnicode совместим с символами 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| \b | Backspace | |
| \f | Form feed/прогон страницы | |
| \n | New line/новая строка | |
| \r | Carriage return/возврат каретки | |
| \t | Tab/табуляция | |
| \' | Апостроф или одинарная кавычка | |
| \" | Двойная кавычка | |
| \\ | Обратный слэш (\) | |
| \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-значения специальных символов| Пробельные символы | \u0009 | Tab/табуляция | |||||
| \u000B | Vertical Tab/вертикальная табуляция | ||||||
| \u000C | Form Feed/прогон страницы | ||||||
| \u0020 | Space/пробел | ||||||
| Терминаторы строки | \u000A | Line Feed/прогон строки | |||||
| \u000D | Carriage Return/возврат каретки | ||||||
| Дополнительные escape-последовательности Unicode | \u000b | Backspace | |||||
| \u0009 | Horizontal Tab/горизонтальная табуляция | ||||||
| \u0022 | Double Quote/двойная кавычка | " | |||||
| \u0027 | Single Quote/одинарная кавычка | ' | |||||
| \u005C | Backslash/обратный слэш | \ |
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, вычисление даст значение 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 предоставляет арифметические операции, перечисленные в таблице.
Битовые логические операции
Битовые логические операцииКонцептуально битовые логические операции работают так:
Операция применяется к каждой паре битов, и результат конструируется побитно.
Например, цифра 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.Приоритет операций
Приоритет операцийПриоритет операций определяет порядок, в котором они выполняются при вычислении выражения. Вы можете переопределить приоритет операций путём использования скобок.
В следующей таблице показан приоритет выполнения операций, от низшего к высшему.
Сокращённый цикл вычисления
Сокращённый цикл вычисленияПоскольку логические выражения вычисляются слева направо, они проверяются на возможность "сокращённого/short-circuit" вычисления по следующим правилам:
true || anything ускоренно вычисляется в true.
Правила логики гарантируют, что эти вычисления всегда корректны. Обратите внимание, что часть anything вышеприведённых выражений не вычисляется, поэтому выполнение полного вычисления не даст никакого эффекта.
Специальные операции
Специальные операцииВ JavaScript имеются следующие специальные операции:
условная операция
delete
this
void
Строковые операции
Строковые операцииПомимо операций сравнения, которые могут использоваться со строковыми значениями, операция конкатенации (+) объединяет два строковых значения, возвращая строку, которая является результатом объединения двух строк-операндов. Например, "my " + "string" возвращает строку "my string".
Операция-аббревиатура присвоения += также может использоваться для конкатенации строк. Например, если переменная mystring имеет значение "alpha", то выражение mystring += "bet" вычисляется в "alphabet" и это значение присваивается переменной mystring.
Операции присвоения
Таблица 3.1 Операции присвоения| x += y | x = x + y |
| x -= y | x = x - y |
| x *= y | x = x * y |
| x /= y | x = x / y |
| x %= y | x = x % y |
| x <<= y | x = x << y |
| x >>= y | x = x >> y |
| x >>>= y | x = x >>> y |
| x &= y | x = x & y |
| x ^= y | x = x ^ y |
| x |= y | x = x | y |
Операции сравнения
Таблица 3.2 Операции сравнения| Равно (==) | Возвращает 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. | ||
| Исключающее ИЛИ/XOR | a ^ 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 имеются следующие типы выражений:
Строковые: вычисляются в строку символов, например, "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. Справочник.
Создание регулярного выражения
Вы конструируете регулярное выражение одним из двух способов:Используя инициализатор объекта:
Инициализаторы объектов выполняют компиляцию регулярного выражения при вычислении скрипта. Если регулярное выражение является константным, используйте инициализатор для повышения производительности. Инициализаторы объектов обсуждаются в разделе "Использование Инициализаторов Объектов".
Вызывая функцию-конструктор объекта RegExp:
Использование функции-конструктора предоставляет компиляцию регулярного выражения на этапе прогона. Это делается, если известно, что патэрн регулярного выражения будет изменяться, или если Вы не знаете патэрн и получаете его из другого источника, такого как пользовательский ввод. После того как регулярное выражение определено, и если оно используется в скрипте и исходное значение изменяется, Вы можете использовать метод 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" | |||
| myRe | lastIndex | Индекс, по которому находится начало следующего совпадения. (Это свойство устанавливается, только если регулярное выражение использует опцию g, описанную в разделе "Выполнение Глобального Поиска и Игнорирование Регистра Символов".) | 5 | ||
| source | Текст патэрна. | "d(b+)d" | |||
| RegExp | lastMatch | Последние совпавшие символы. | "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 прерывается.
Выполняется выражения обновления incrementExpression, и управление возвращается к шагу 2.
Пример. Эта функция содержит оператор for, подсчитывающий количество выбранных опций в прокручиваемом списке (объекте Select, который позволяет делать множественный выбор). Оператор for объявляет переменную i и инициализирует её значением 0 (нуль). Если i меньше количества опций объекта Select, выполняется следующий оператор if, а i увеличивается на 1 при каждом прохождении цикла.
Оператор 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 есть несколько предопределённых функций: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. Вы можете всегда обратиться к объектам в этих массивах по порядковому номеру (в зависимости от места в документе) или по именам (если определены). Например, если второй тэг
Массивы и регулярные выражения
Массивы и регулярные выраженияЕсли массив является результатом совпадения регулярного выражения и строки , этот массив возвращает свойства и элементы, которые предоставляют информацию о совпадении. Массив является тогда return-значением regexp.exec, string.match и string.replace. Об использовании массивов с регулярными выражениями см. Главу 4 "Регулярные Выражения".
Методы объекта Array
Методы объекта ArrayОбъект Array имеет следующие методы:
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 для работы с датами и временем распадаются на следующие обширные категории:
"get"-методы для получения значений даты и времени из объектов Date.
"to"-методы для возвращения строковых значений из объектов Date.
parse и UTC-методы для разбора Date-строк.
Методами "get" и "set" Вы можете получать и устанавливать значения для секунд, минут, часа, дня недели, числа месяца, месяца и года. Имеется метод getDay, который возвращает день недели, но нет па́рного метода setDay, поскольку день недели устанавливается автоматически. Эти методы используют целые числа для представления этих значений:
Час: от 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 может быть одним из:
Строкой, представляющей дату в следующей форме: "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++, помогут понять две разных сущности: класс и экземпляр.Экземпляр, с другой стороны, это инстанциация класса; то есть это один из членов класса. Например, 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 в 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 Вы специфицируете суперкласс в определении класса. Вы не можете изменить суперкласс вне определения класса.
| 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 новыми значениями, специфичными для этих объектов.
| 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 = ""; } } |
ПРИМЕЧАНИЕ:
Термин экземпляр\instance имеет специфическое техническое значение в языках программирования на базе классов. В них экземпляр это отдельный член класса, фундаментально отличающийся от класса. В JavaScript "экземпляр/instance" не имеет этого технического значения, поскольку JavaScript не различает классы и экземпляры. Однако, говоря о JavaScript, "экземпляр" может использоваться неформально для обозначения объекта, созданного с использованием конкретной функции-конструктора. Так, в данном примере, Вы можете неформально сказать, что jane это Engineer-экземпляр. Аналогично, хотя термины parent\родитель, child\дочерний, ancestor\предок и descendant\потомок не имеют формальных значений в JavaScript, Вы можете использовать их неформально для обращения к объектам выше или ниже по цепочке прототипов.
Создание объектов с помощью простых определений
Рисунок 8.3 Создание объектов с помощью простых определений
В таблице показаны определения Java
Рисунок 8.5 Специфицирование свойств в конструкторе, этап 1
В таблице показаны определения Java и JavaScript для этих объектов.
| 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; } } |
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)
| Класс и экземпляр это разные сущности. | Все объекты являются экземплярами. | ||
| Класс определяется в определении класса; инстанциация (создание экземпляров) производится методами-конструкторами. | Набор объектов создаётся и определяется функциями-конструкторами. | ||
| Одиночный объект создаётся операцией 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
Как и в 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 в теле тэга
...