Перспективные технологии и языки веб-разработки

JavaScript - язык разработки клиентских веб-приложений

Показывать лекцию целиком

JavaScript - интерпретируемый язык программирования, стандартизированный международной организацией ECMA в спецификации ECMA-262. Языки JavaScript, JScript и ActionScript являются расширением стандарта ECMA-262.

Название "ECMAScript" явилось фактически компромиссом между организациями, вовлеченными в процесс стандартизации, в частности Netscape и Microsoft. Хотя JavaScript и JScript стремились к совместимости с ECMAScript, они имеют ряд дополнительных возможностей не предусмотренных спецификацией ECMA.

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

  • автоматизация администрирования систем Microsoft Windows;
  • создание страниц ASP.
  • Язык JScript получил дальнейшее развитие в виде языка JScript.NET, который ориентирован на работу в рамках платформы Microsoft.NET

    JavaScript - интерпретируемый, объектно-ориентированный язык. Хотя он имеет существенно меньшее количество возможностей, чем такие объектно-ориентированные языки как C++ и Java.

    Распространенным заблуждением является то, что JavaScript аналогичен или тесно связан с Java. Оба языка имеют C-подобный синтаксис, являются объектно-ориентированными и как правило широко используются в клиентских веб-приложениях, однако:

    Java JavaScript
    использует парадигму ООП из C++ использует прототипный подход
    имеет статическую типизацию имеет динамическую типизацию (значение переменной может содержать объекты любого типа и даже функции)
    загружается из скомпилированного байт-кода интерпретируется напрямую из файла.

    Структура языка

    Структурно JavaScript можно представить в виде объединения трех четко различимых друг от друга частей:

  • ядро (ECMAScript),
  • объектная модель браузера (Browser Object Model),
  • объектная модель документа (Document Object Model или DOM).
  • Ядро

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

    Объектная модель браузера

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

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

  • управление фреймами;
  • исполнении кода и зацикливания с задержкой;
  • системные диалоги;
  • управление адресом открытой страницы;
  • управление информацией о браузере;
  • управление информацией о параметрах монитора;
  • ограниченное управление историей просмотра страниц;
  • поддержка работы с HTTP cookie.
  • Объектная модель документа

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

  • получение узлов,
  • изменение узлов,
  • изменение связей между узлами,
  • удаление узлов.
  • Основы JavaScript (ECMAScript)

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

  • язык не позволяет разрабатывать самостоятельные приложения;
  • сценарии на JavaScript могут выполняться только при помощи интерпретатора, в частности веб-браузером.
  • JavaScript - язык без строгого контроля типов. Поэтому не требуется объявлять тип переменных явно. Кроме того, во многих случаях JavaScript исполняет преобразования автоматически, когда они необходимы. Например, при сложении строки и числа, число будет преобразовано в строку.
  • Код на JavaScript пишется в текстовом формате, и организован в инструкции, блоки, состоящие из связанных наборов инструкций, и комментариев. В пределах инструкции можно использовать переменные и данные, такие как строки, числа и выражения. Для объявления конца инструкции используется точка с запятой ;. Группа JScript-инструкций, заключенная в фигурные скобки {}, называется блоком.

    Комментарием в JavaScript является текст, расположенный после // до конца строки. Многострочный комментарий начинается с /*, и заканчивается */.

    Знак равенства (=) используется в JavaScript как присваивание. Следующий код

    Pi = 3.14;
    

    подразумевает "Присвоить значение 3.14 переменной Pi".

    При сравнении двух значений на равенство применяется двойной знак равенства (==).

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

    Объявление переменной перед использованием является необязательным. Для этого используется инструкция var. Инструкция var является обязательной при объявлении локальной переменной внутри функции. Разрешается объявление переменной неявно - без инструкции var. Однако, в выражениях применять необъявленные переменные не допускается. JavaScript различает регистр в имени переменной. Name и name рассматриваются как различные переменные.

    Типы данных

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

    В JavaScript используется шесть типов данных. Основные из них - числа, строки, объекты, логический. Остальные два - null и undefined (т.е. неопределенный).

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

    JavaScript поддерживает числа как целые, так и с плавающей запятой. Также существуют специальные представления чисел, например NaN (не число).

    Примеры чисел:

    3.14 // Вещественное число
    15 // Целое число
    0177 // Восьмеричное число 177
    0XA8    // Шестнадцатиричное число A8
    

    Логический тип допускает значения - true и false. Любое выражение, равное 0, считается эквивалентным false, а любое выражение, равное числу, отличному от 0 будет эквивалентным true.

    Undefined - означает, что тип не определен. Значение undefined имеет переменная после ее объявления и до присвоения ей какого-либо определенного значения.

    Переменная типа null - не имеет никакого определенного значения.

    Операторы

    Язык поддерживает условные выражения if и if...else. При использовании нескольких условий одновременно можно использовать операторы ||(ИЛИ ) или (И).

    В JavaScript существует несколько типов циклов: for, for...in, while, do...while и switch. Также существует инструкция остановки выполнения цикла. Оператор завершения break может применяться для того, чтобы остановить цикл, при выполнении какого-либо условия. Инструкция continue используется, чтобы немедленно перейти к выполнению следующей итерации, пропуская остальную часть выполнения кода текущей итерации, но обновляя переменную-счетчик.

    Функции

    В JavaScript имеется два вида функций: встроенные и определяемые. Программист имеет возможность создавать собственные функции. Определение функции состоит из объявления параметров и блока инструкций JavaScript.

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

    function имя (аргументы) 
    {
      операторы
    }
    

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

    Пример:

    function area(radius) 
    {
      return   pi* radius *  radius;
    }
    

    Эта функция называется area и имеет один формальный аргумент radius. При вызове этой функции вместо формального аргумента подставляется его фактическое значение, функция вычисляет площадь круга на основе этого значения и возвращает полученное число через оператор return.

    Переменные, декларированные в теле функции, являются локальными, т. е. недоступны вне ее тела.

    При вызове функции в JavaScript действуют следующие правила передачи аргументов функции:

  • Аргументы примитивных типов передаются функции по значению.
  • Объекты (и встроенные, и определенные пользователем) передаются по ссылке. Это означает, что все изменения свойств объекта в теле функции производятся непосредственно в самом объекте, а не в его локальной копии и, следовательно, сохраняются после возврата из функции.
  • В JavaScript функция выступает в качестве одного из основных типов данных. Одновременно с этим в JavaScript определен класс объектов Function.

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

  • функция как тип данных;
  • функция как объект;
  • функция как конструктор объектов.
  • Объекты

    Объект - это главный тип данных JavaScript. Объекты в JavaScript, по-сути, являются совокупностями методов и свойств.

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

    Сценарии JavaScript могут использовать объекты следующих видов:

  • клиентские объекты, входящие в модель DOM, т.е. отвечающие тому, что содержится или происходит на Web-странице в окне браузера. Они создаются браузером при разборе (парсинге) HTML-страницы. Примеры: window, document, location, navigator и т.п.
  • серверные объекты, отвечающие за взаимодействие клиент-сервер.
  • встроенные объекты, представляющие различные типы данных, свойства, методы, присущие самому языку JavaScript, независимо от содержимого HTML-страницы. Примеры: Array, String, Date, Number, Function, Boolean, Math.
  • пользовательские объекты, которые создаются программистом в процессе создания сценария с использованием конструкторов типа объектов (класса).
  • Операторы работы с объектами

    Оператор for (переменная in объект) позволяет перебрать все свойства объекта. Например:

    for (d in document)
      document.write("document."+d+" = <b>"+ 
              document[d]+"</b><br>");
    

    Обработка объектов и массивов идентична. Можно обратиться к любой части объекта (его свойствам и методам) либо по имени, либо по индексу.

    Клиентские объекты

    Для создания механизма управления страницами на клиентской стороне используется объектная модель документа (DOM - Document Object Model). Суть модели в том, что каждому HTML-контейнеру соответствует объект, который характеризуется:

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

    Связи между объектами различных уровней, представленные на рис. 6.1, означают, что объект верхнего уровня содержит ссылку на объект нижнего уровня. Так, например, между объектами Window и Document есть связь. Это означает, что объект Window имеет свойство с именем document, содержащее ссылку на объект типа Document.

    (рис 6.1) Иерархия объектов в окне браузера.

    Исключением является объект Location. Из рис. 6.1 видно, что на этот объект ссылается как объект Window, так и объект Document. В объекте Document ссылка на объект Location также содержится в свойстве с именем location.

    Некоторые интерпретаторы JavaScript считают, что свойство location объекта Document должно быть защищено от записи. Поэтому обращение к объекту Location через свойство location объекта Window и через одноименное свойство объекта Document могут дать различные результаты.

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

    объект.свойство
    

    или

    объект.метод()
    

    Первый объект, с которым необходимо познакомиться, чтобы написать простейший сценарий, - это объект document, который описывает HTML документ, отображаемый в окне браузера. Ниже приведен исходный текст веб-страницы, содержащей сценарий, действия которого сводятся к выводу строки текста в окне браузера.

    Имена чувствительны к регистрам символов, и если вы попытаетесь обратиться к текущему документу по имени Document, интерпретатор JavaScript отобразит сообщение об ошибке.

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

  • links[ ] - массив ссылок на гипертекстовые связи, сформированные в HTML-документе с помощью дескрипторов <А>.
  • images[ ] - массив ссылок на изображения, включенные в состав Web-страницы с помощью дескрипторов <IMG>.
  • forms[ ] - массив ссылок на формы, созданные посредством дескрипторов <FORM>.
  • Объекты Link, Image и Form помещаются в массивы links[], images[] и forms[] в том же порядке, в котором они встречаются в исходном тексте HTML-документа. Так, images[0] ссылается на первое изображение в составе веб-страницы, images[1] - на второе изображение и т.д.

    Объект Form, в свою очередь, ссылается на интерактивные элементы, принадлежащие форме. Несмотря на то, что каждый из элементов является объектом определенного типа (например, Text, Password, Radio, Checkbox и т.д.), для их описания существует также обобщенный тип Element. Соответственно ссылки на интерактивные элементы, принадлежащие форме, содержатся в свойстве elements объекта Form. Так, чтобы получить строку текста, которую пользователь ввел в поле формы, расположенной на веб-странице, можно использовать следующее выражение:

    line = document.forms[0].elements[2].value;
    

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

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

    Массивы

    Массивы в JavaScript могут быть встроенными, или коллекциями, (например, document.links, document.images) и определяемые пользователем. Коллекции будут обсуждаться в следующей лекции. Для массивов определено несколько методов: join(), reverse(), sort() и другие. Свойство length позволяет узнать количество элементов в массиве.

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

    a = new Array();
    // пустой массив 
    
    b = new Array(17);
    // массив длины 17
    
    c = new Array(10, '12345');
    // массив из двух элементов: числа и строки
    

    Элементы массива нумеруются с нуля. В языке JavaScript массив может состоять из разнородных элементов. Элементами массива могут быть также массивы.

    Встраивание JavaScript в веб-страницы

    Возможны 3 варианта встраивания JavaScriptкода в веб-страницы:

  • Расположение внутри страницы. Для добавления JavaScript-кода на страницу, можно использовать теги <script></script>.

    Наример:

    <script type="text/javascript">
      alert('Hello, World!');
    </script>
    
  • Расположение внутри тега. Спецификация HTML описывает набор атрибутов, используемых для задания обработчиков событий. Пример использования:
    <a href="delete.php" 
      onclick="return confirm('Вы уверены?');">
      Удалить
    </a>
    
  • Вынесение в отдельный файл. Можно сохранить сценарий в отдельном файле, а потом подключить его с помощью конструкции
    <script type="text/javascript" 
      src="URL_файла_со_сценарием"></script>
    
  • Обработка событий в JavaScript

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

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

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

    Имя обработчика определяет, какое событие он должен обрабатывать. Так, для того чтобы сценарий нужным образом отреагировал на щелчок мышью, используется обработчик с именем onClick, для обработки события, заключающегося в получении фокуса ввода, - обработчик onFocus.

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

    имя_обработчика="команды_обработчика"
    

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

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

    <input type="text" name="Inform" 
        onFocus="handleFocus();">
    

    Имя обработчика является одним из атрибутов HTML-дескриптора, а команды, предназначенные для обработки события, выступают в роли значения этого атрибута. В данном случае обработка события производится в теле функции handleFocus(). В принципе, обработчиком может быть не только функция, но и любая последовательность команд JavaScript в виде составного оператора.

    Следующий пример демонстрирует обработку события, связанного с наведением курсора мыши на гиперссылку:

    <a href = "http://www.myhp.edu" onmouseover="alert('Событие onMouseOver');   
        return false">
      <img src="my.gif" width="50" height="50"> 
    </a>
    

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

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

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

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

    При описании структуры шаблона используются:

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

    Представление Позиция
    ^ Начало строки
    $ Конец строки
    \b Граница слова
    \B Не граница слова
    (?=шаблон) Искомая строка следует после указанной строкой (с просмотром вперед)
    (?!=шаблон) Искомая строка не следует после указанной строки (с просмотром вперед)
    (?<=шаблон) Искомая строка следует после указанной строкой (с просмотром назад)
    (?<!шаблон) Искомая строка не следует после указанной строки (с просмотром назад)

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

    Представление Число повторений
    {n} Ровно n
    {m, n} От m до n включительно
    {m,} Не менее m
    {,n} Не более n

    Имеются и более простые квантификаторы:

    Представление Число повторений Эквивалент
    * Ноль или более {0,}
    + Одно или более {1,}
    ? Ноль или одно {0,1}

    Для задания внутри шаблона группы символов можно использовать следующие операторы:

    Оператор Описание
    [xyz] Любой символ из указанного множества
    [^xyz] Любой символ не входящий в указанное множество
    [x-z] Любой символ из указанного диапазона
    [^x-z] Любой символ не входящий в указанный диапазон
    . (точка) Любой символ кроме символов разрыва или переноса строки
    \w Любой буквенно-цифровой символ, включая символ подчеркивания
    \W Любой не буквенный символ
    \d Любая цифра
    \D Любой нецифровой символ
    \s Любой не отображаемый символ
    \S Любой символ (кроме неотображаемых символов)

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

    Оператор Описание
    ( ) Поиск группы символов внутри скобок и сохранение найденного соответствия
    (?: ) Поиск группы символов внутри скобок без сохранения найденного соответствия
    | Комбинирование частей в одно выражения с последующим поиском любой из частей в отдельности. Аналогично оператору "ИЛИ".

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

    Обозначение Описание
    \0 Символ с нулевым кодом
    \n Символ новой строки
    \r Символ начала строки
    \t Символ табуляции
    \v Символ вертикальной табуляции
    \xxx Символ, имеющий заданный восьмеричный ASCII код xxx
    \xdd Символ, имеющий заданный шестнадцатиричный ASCII код dd
    \uxxxx Символ, имеющий ASCII код выраженный ЮНИКОДОМ xxxx

    Квантификаторам в регулярных выражениях соответствует максимально длинная строка из возможных (т.е. квантификаторы являются "жадными"). Это может приводить к некоторым проблемам. Например, шаблон (<.*>) описывающий на первый взгляд теги HTML на самом деле будет выделять более крупные фрагменты в документе.

    Например, строка вида

    <p>
      <font color='blue'>
        <i>Регулярные выражения<i>
      </font> 
      - удобный инструмент для поиска в строках 
    </p>
    

    формально соответствует указанному выше шаблону

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

  • В регулярном выражении учитываются символы, не соответствующие желаемому образцу (например, <[^>]*> для вышеописанного случая).
  • Определение квантификатора как нежадного (ленивого) - большинство реализаций позволяют это сделать, добавив после него знак вопроса.
  • Например, по шаблону (<.*?>) будут найдены все теги из рассмотренной строки.

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

    Квантификатор Описание
    *? "не жадный" эквивалент *
    +? "не жадный" эквивалент +
    {n,}? "не жадный" эквивалент {n,}

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

    Примеры регулярных выражений.

  • Дата в формате yyyy-MM-dd:
    20\d\d\-(0[1-9]|1[0-2])\-(0[1-9]|[12][0-9]|3[01])
    
  • IP адрес:
    \b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
    
  • Доменное имя:
    ^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$
    
  • Вещественное число:
    [-+]?(?:\b[0-9]+(?:\.[0-9]*)?|\.[0-9]+\b)(?:[eE][-+]?[0-9]+\b)?
    
  • Запись числа в римской системе счисления:
    ^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$
    
  • Регулярные выражения в JavaScript

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

    Для объекта объекта RegExp поддерживаются следующие методы:

  • Конструктор RegExp. В аргументе задается регулярное выражение.
  • Метод test выполняет поиск по шаблону.
  • Метод exec выполняет поиск подстроки по шаблону и возвращает найденные соответствия; если соответствий нет, возвращается значение null.
  • Метод compile применяется для изменения ранее созданного шаблона.
  • Аргументом в последних трех методах является строка, в которой выполняется поиск по шаблону.

    Вернуться к учебному плану