Internet Explorer 5.0 — новые версии скриптовых языков
Методы Execute и ExecuteGlobal
Сравнение JScript с Java и C++
Что нового в Netscape JavaScript 1.3
В состав Internet Explorer 5.0 входят обновленные версии скриптовых языков — VBScript 5.0 и JScript 5.0. Эти версии, входящие в состав браузера, автоматически становятся доступными и для Active Server Pages (ASP), и для Windows Scripting Host (WSH). В этом обзоре мы рассмотрим основные новинки, появившиеся в VBScript 5.0 и JScript 5.0.
Для того чтобы использовать новые версии скриптовых языков, не обязательно переходить на Internet Explorer 5.0 — достаточно просто загрузить соответствующие файлы, которые обеспечат поддержку VBScript 5.0 и JScript 5.0 в браузерах Internet Explorer 3.0 и 4.0.
За два с небольшим года скриптовые языки прошли путь от версии 1.0, появившейся в Internet Explorer 3.0, до 5.0 — версии, полностью совместимой со стандартом ECMAScript (язык JScript) и обладающей новыми возможностями VBScript.
В таблице перечислены версии скриптовых языков, доступные в различных продуктах фирмы Microsoft.
Продукт | VBScript | JScript |
---|---|---|
Microsoft Internet Explorer 3.0 | 1.0 | 1.0 |
Microsoft Internet Information Server 1.0 | 2.0 | 2.0 |
Microsoft Internet Explorer 4.0 | 3.0 | 3.0 |
Microsoft Internet Information Server 4.0 | 3.0 | 3.0 |
Microsoft Windows Scripting Host 1.0 | 3.0 | 3.0 |
Microsoft Visual Studio 6.0 | 4.0 | 4.0 |
Microsoft Internet Explorer 5.0 | 5.0 | 5.0 |
Microsoft Internet Information Server 5.0 | 5.0 | 5.0 |
Прежде чем перейти к рассмотрению новинок, появившихся в скриптовых языках, отметим, что Microsoft развивает параллельно и VBScript и JScript. Если перспективность использования VBScript в Internet вызывает вполне закономерные сомнения, то для создания интрасетевых (Intranet) приложений (когда точно известны тип и версия клиентского браузера), а также для использования в составе ASP-приложений и программ для Windows Scripting Host этот язык вполне пригоден. Принятие стандарта ECMAScript, задавшего основные требования к языку Jscript, не вызвало приостановки его развития — в версии 5.0 есть ряд новинок, которые, возможно, станут частью будущего стандарта.
VBScript 5.0
Новые возможности появившиеся в VBScript 5.0, ставят этот язык на один уровень с JScript. К ним относятся:
-
поддержка регулярных выражений;
-
поддержка классов;
-
новый оператор With;
-
новые методы Eval, Execute и ExecuteGlobal;
-
возможность работы с DCOM.
Кроме того, существенно повышена производительность VBScript-программ, исполняемых в составе HTML-страниц в Internet Explorer 5.
Регулярные выражения
Поддержка регулярных выражений — механизма для манипуляции строками по заданным шаблонам, хорошо известного разработчикам на языке Perl, а с недавнего времени — и на JScript, делает язык VBScript все более привлекательным для разработки серьезных программ.
Новый объект RegExp, реализующий ту же самую объектную модель, что и в JScript, основан на использовании коллекций. Сам же синтаксис регулярных выражений остался точно таким же, как и в JScript (а он, в свою очередь, основан на синтаксисе Perl).
Давайте рассмотрим небольшой пример. Предположим, что нам необходимо проверять правильность ввода адреса электронной почты в форме — он должен состоять из двух частей, разделенных символом @. Сначала мы создадим переменную mailReg, представляющую собой экземпляр объекта RegExp:
Dim mailReg Set mailReg = new RegExp
После этого можно задать шаблон регулярного выражения, который в нашем случае будет таким:
\w+\@[.\w]+
C помощью данного шаблона мы можем проверять, есть ли в строке слово, за которым следует символ @ и еще одно слово. Шаблон задается как значение свойства pattern:
mailReg.pattern = “\w+\@[.\w]+”
После того как шаблон задан, мы можем использовать метод test для проверки соответствия какой-либо строки данному шаблону. Этот метод возвращает булево значение, указывающее результат проверки. Вот полный код данного примера:
<body> <script language=”VBScript”> Sub mail_check dim mailReg set mailReg = new RegExp mailReg.pattern = “\w+\@[.\w]+” if mailReg.Test(mailForm.email.value) then alert(“Все в порядке”) else alert(“Адрес указан неверно”) mailForm.email.focus() end if End Sub </script> <form name=”mailForm”> <input name=”email”> <input type=”button” onClick=”mail_check”> </form> </body>
В VBScript 5.0 поддержка регулярных выражений реализована в виде COM-объекта. Таким образом, установив Internet Explorer 5.0, вы можете использовать механизм проверки регулярных выражений в любом средстве, поддерживающем COM. Например, мы можем использовать проверку регулярных выражений в Delphi:
procedure TForm1.Button1Click(Sender: TObject); var RegExp : variant; begin RegExp := CreateOLEObject(‘VBScript.RegExp’); RegExp.pattern := ‘\w+\@[.\w]+’; if RegExp.Test(Edit1.Text) Then ShowMessage(‘ Все в порядке ‘) Else ShowMessage(‘ Адрес указан неверно ‘) end;
Классы
В JScript и Visual Basic есть возможность создания новых объектов. Это можно делать на основе либо прототипа (JScript), либо классов (Visual Basic). Создание новых объектов облегчает работу над комплексными программами, позволяя применять к ним методы объектно-ориентированного дизайна.
В VBScript 5.0 появилась возможность создания классов с использованием оператора Class. Свойства и методы класса задаются так же, как и в Visual Basic, — путем использования ключевых слов Public, Private и Property. Но в отличие от Visual Basic в VBScript классы не хранятся в отдельных cls-файлах.
Рассмотрим следующий пример. Пусть мы хотим создать класс, в котором бы хранились данные о пользователе — его имя, адрес электронной почты и дата посещения страницы. Для этого мы можем создать класс WebUser:
Class WebUser Public sName, sEMail, dVisitDate Property Get Name Name = sName End Property Property Let Name(strName) sName = strName End Property ‘ ‘ и так далее ‘ End Class
После того как класс описан, мы можем использовать его в нашем коде:
Dim newWebUser Set newWebUser = new WebUser newWebUser.Name = userForm.NameField ‘ ‘ и так далее ‘
Отметим, что использование классов позволяет нам инкапсулировать бизнес-логику и сделать программу более модульной.
Оператор With
В скриптовых программах, будь то программы, использующие Dynamic HTML или объектную модель ASP, часто вызываются методы и изменяются значения свойств различных объектов. Помимо того что на написание имени того или иного объекта в каждой строке уходит время, такой код не является производительным: при каждом обращении к методу или свойству приходится обращаться и к копии объекта, находящейся в памяти.
Для решения этой проблемы в VBScript 5.0 был введен оператор With, позаимствованный из Visual Basic. Этот оператор позволяет указать объект, над которым будут производиться действия, и объединить эти действия в отдельный блок. Внутри блока имя объекта уже не указывается — контекст задан с помощью оператора With.
Рассмотрим следующий пример. Пусть нам требуется динамически изменить ряд атрибутов какого-нибудь элемента HTML-страницы. Для этого мы должны выполнить ряд обращений к свойству style:
элемент.style.атрибут = новое_значение
Используя оператор With, мы можем написать такой код:
With элемент.style .атрибут = новое_значение End With
Сравните следующие примеры кода:
Без оператора With С оператором With <SCRIPT LANGUAGE=”VBScript”> sub change() para.style.background = “#a7c7b7” para.style.fontFamily = “Courier” para.style.fontWeight = 700 end sub </SCRIPT> <SCRIPT LANGUAGE=”VBScript”> sub change() With para.style .background = “#a7c7b7” .fontFamily = “Courier” .fontWeight = 700 End With end sub </SCRIPT>
Eval, Execute и ExecuteGlobal
Метод Eval, реализованный в JScript, позволяет производить различные вычисления во время работы программы и даже выполнять программы на JScript внутри программ на JScript. В VBScript 5.0 также реализована такая возможность, но с помощью трех методов — Eval, Execute и ExecuteGlobal. Это вызвано семантическими различиями в двух языках. Если в JScript оператор «=» используется только для присвоения значений переменным, а операторы «==» и «===» служат для сравнения значений, то в VBScript оператор «=» используется и для присвоения значений и для сравнения.
Метод Eval
Данный метод используется для вычисления значений во время выполнения программы. Метод Eval возвращает значение вычисленного выражения. Кроме того, с помощью этого метода можно динамически генерировать различные выражения и получать результат их вычислений. Это особенно полезно при работе с Dynamic HTML, когда объекты создаются по мере работы программы, — в этом случае единственным способом доступа к их свойствам является метод Eval.
Методы Execute и ExecuteGlobal
Эти два метода позволяют выполнить серию выражений VBScript в процессе работы программы. Метод Execute работает с локальным пространством имен и обеспечивает доступ к локальным переменным. Для доступа к глобальным переменным, например при добавлении классов, следует использовать метод ExecuteGlobal.
Указатели на функции
Как известно, в Dynamic HTML есть возможность присвоения обработчиков событий во время работы программы. Это бывает полезно в тех случаях, когда мы динамически создаем сами объекты и соответствующий код, например, используя метод Eval. В Internet Explorer 4.0 единственным способом динамического присвоения обработчиков событий было использование стандартной конструкции
Sub objectname_eventname ()
или задание обработчика в элементе BODY:
<body onload=”foo()”>
Оба этих механизма позволяли задавать методы статически. Напомним, что в JScript для динамического задания обработчика события мы можем использовать такой код:
window.onclick = wnd_click
Теперь и в VBScript появилась такая возможность. Для этого в язык введен указатель на функцию — GetRef, использование которого позволяет проводить динамическое задание обработчика следующим образом:
set window.onclick = getref(“wnd_click”)
Поддержка DCOM
Distributed COM (DCOM) обеспечивает возможность вызова COM-объектов, расположенных на удаленных компьютерах. Поддержка вызова таких объектов была добавлена в новых версиях VBScript и JScript. В методе CreateObject появился новый параметр, позволяющий задать имя сервера, на котором располагается вызываемый COM-объект. Например:
Set newObject = CreateObject(“ObjectName”, “\\servername”)
После того как экземпляр объекта newObject будет создан, с ним можно работать как с обычным локальным объектом.
JScript 5.0
В новой версии JScript разработчикам следует обратить внимание на механизм поддержки обработчиков исключений, а также на новый параметр конструктора ActiveXObject.
Обработка исключений
Основной новинкой в JScript 5.0 стала поддержка обработки исключений, построенная на основе операторов try/catch, знакомых многим разработчикам на С++ и Java. Следует отметить, что введение этого механизма обсуждалось с членами комитета по разработке стандарта ECMAScript, и, скорее всего, данный механизм станет частью новой спецификации языка ECMAScript.
Обработка исключений — это механизм, позволяющий обрабатывать ошибки, возникающие во время выполнения кода. Сама идея обработки возникающих ошибок не является новой, но лишь относительно недавно программисты получили возможность создавать собственные обработчики исключений. Давайте начнем с того, что рассмотрим, как обработка ошибок выполняется «традиционными» способами.
// Создадим экземпляр объекта var someObj = Server.CreateObject(“SomeServerComponent”); // Если он не создался if (someObj == null) { Обработаем ошибку создания объекта } else { // Получим возможный код ошибки var err_code = someObj.getErrCode(); // И обработаем его switch (err_code) { case 0 : ...; break; case 1 : ...; break; ... } } // Здесь располагается код, выполняемый, если все в порядке
Приведенный здесь код вполне справляется с поставленной задачей — обрабатывает ошибки, которые могут возникнуть в процессе выполнения программы. Единственная проблема в том, что этот код, встроенный в код, реализующий логику работы программы, труден для понимания и сопровождения. Более того, при возникновении ошибки нарушается логика работы программы, и для ее поддержания мы должны использовать сложные языковые конструкции. Всех этих проблем можно избежать, если использовать обработчики исключений.
Вместо того чтобы возвращать код ошибки, многие объекты могут сообщать о возникновении исключительной ситуации. В этом случае управление передается блоку кода, написанного специально для обработки такой ситуации. Вернемся к нашему примеру. При наличии поддержки обработки исключений мы могли бы написать такой код:
try { // Создадим экземпляр объекта var someObj = Server.CreateObject(“SomeServerComponent”); ... } catch (exception) { // Здесь располагаются обработчики исключений } // Здесь располагается код, выполняемый, если все в порядке
В данном примере мы помещаем в блок try код, выполнение которого может вызвать исключение, а в блоке catch обрабатываем возможные исключения.
После того как мы выяснили, что использование обработчиков исключений делает наш код более наглядным и, возможно, более элегантным, давайте сравним обработку исключений в JScript, Java, C++ и VBScript.
Сравнение JScript с Java и C++
Как известно, синтаксис JScript основан на синтаксисе Java и С++. Естественно было бы предположить, что и синтаксис обработчиков исключений схож с этими языками, тем более что эти механизмы в Java и C++ похожи. Ниже мы увидим, так ли это на самом деле.
Механизм обработки исключений в Java и C++ базируется на операторах try/catch. Ключевое слово try предшествует блоку кода, который может вызвать возникновение исключительной ситуации, а блок catch содержит обработчик этой ситуации. Вот синтаксис, используемый в C++, Java и JScript:
try { // Код, который может вызвать возникновение исключения } catch (declaration) { // Код, выполняемый при возникновении исключения }
Основным отличием в обработке исключений в Java, C++ и JScript является описание для catch и то, как оно используется для выполнения кода. В Java это описание является экземпляром класса, расширяющего стандартный класс Throwable. Например, при доступе к COM-объекту в блоке try в Visual J++ вы используете класс com.ms.com.ComFailException:
catch (com.ms.com.ComFailException e) { // Код, выполняемый в случае возникновения исключений // типа com.ms.com.ComFailException }
В С++ можно использовать либо экземпляр стандартного класса exception, либо любой другой тип, например строку:
catch ( char *errMsg ) { // Код, выполняемый в случае, когда исключение имеет // тип указателя на символ }
В JScript также можно использовать любую переменную:
catch (exception) { // Код, который будет выполняться при возникновении // любого исключения }
Отметим, что в JScript в блоке catch нельзя указывать тип переменной, так как он может изменяться — исключение может иметь любой поддерживаемый в JScript тип. Это является еще одним отличием между JScript и Java или C++. И в Java, и в C++ можно использовать несколько блоков catch, в которых порядок выполнения определяется заданным типом. Например, в С++ можно написать следующий код:
try { // someMethod может стать источником исключения типа // Foo или исключения типа Bar someObject.someMethod(someParameters); } catch (Foo foo) { // Код, выполняемый в случае, когда возникло // исключение типа Foo } catch (Bar bar) { // Код, выполняемый в случае, когда возникло // исключение типа Bar }
В C++ и Java мы также можем перехватывать любые или все исключения внутри одного блока. Синтаксис в C++ будет следующим:
catch (...)
В Java синтаксис будет таким:
catch (Throwable t)
В JScript версии 5.0 возможно использование только одного блока catch. Таким образом, тип исключения проверяется внутри этого блока путем использования соответствующих методов языка. Например:
try { // someMethod выдает объект someObjectError при возникновении // ошибки и указывает типы ошибок в свойстве Category someObject.someMethod(someParameters); } catch (exception) { // Этот код будет выполняться для всех исключений, // которые могут произойти при выполнении метода // someMethod. // Проверим, является ли исключением типа // someObjectError if (exception instanceof someObjectError) { if (exception.Category == “Foo”) { // Произошла ошибка типа Foo } else if (exception.Category == “Bar”) { // Произошла ошибка типа Bar } } }
Приведенный выше код требует всего одного пояснения — использования instanceof. В JScript мы должны четко определить тип исключения, тогда как в C++ и Java это происходит автоматически — блок catch не выполняется, если типы не совпадают. Отметим, что разработчик объекта someObject должен определить и объект someObjectError где-то в коде JScript.
Есть еще одно различие в работе блока catch в JScript по сравнению с C++ и Java. Но прежде чем мы его рассмотрим, следует сказать несколько слов о генерации исключительных ситуаций. В C++ и Java существует оператор throw, позволяющий создать исключительную ситуацию. Например, в C++, Java и JScript поддерживается следующий синтаксис:
throw declaration;
Как и в случае с try…catch, разница заключается в том, каким может быть аргумент throw. В Java аргумент должен иметь тип Throwable, в C++ и JScript допустимо использование переменной любого типа.
В Java и C++ есть синтаксические конструкции, позволяющие указать, могут ли создаваемые вами функции генерировать исключения, и даже то, что код, вызывающий такие функции, должен обрабатывать исключения. Это позволяет, посмотрев на объявление функции, узнать, какие проблемы может вызвать ее выполнение. В JScript все намного проще — оператор throw может располагаться в любом месте кода и его аргументом может быть переменная любого допустимого в JScript типа.
Теперь вернемся к тому, в чем заключаются отличия в обработке блока catch в JScript. Если вы внимательно посмотрели на приведенный выше пример обработчика исключений на JScript, то, вероятно, заметили, что он работает не так, как соответствующий обработчик для C++/Java. Если исключение не обрабатывается в C++ или Java, то есть отсутствует блок catch, соответствующий типу произошедшего исключения, и не используется блок «перехватить все», то исключение автоматически передается более высокоуровневому обработчику. В JScript все по-другому, так как используется единый блок catch для всех исключений. В данном случае, для того чтобы пример на JScript работал аналогично примеру на C++/Java, мы должны выполнить следующий код, в случае когда exception.Category не является ни «Foo», ни «Bar»:
// Это не “наше” исключение – передадим его // более высокоуровневому обработчику throw exception;
В JScript позволяется использование вложенных обработчиков исключений — вы можете включать блоки try…catch внутри блоков try…catch и таким образом реализовать обработчики разных уровней. Если же исключение не может быть обработано обработчиком самого верхнего уровня, оно будет обработано браузером: пользователь увидит соответствующее сообщение об ошибке — либо в диалоговой панели, либо на экране браузера.
Сравнение JScript с VBScript
Возможности по обработке ошибок в VBScript — это небольшое подмножество того, что имеется в Visual Basic. В VBScript мы можете «включить» обработку ошибок с помощью оператора On Error Resume Next:
Sub test ... On Error Resume Next ‘ включить обработку ошибок ‘ на время выполнения всего кода ... End Sub
Если ошибка в процедуре test произошла до строки, содержащей оператор On Error, выполнение всей процедуры будет завершено. Также будет завершено и выполнение процедуры, вызвавшей процедуру test. Так будет происходить по всей цепочке вызовов. Затем управление получит обработчик ошибок.
Если же ошибка произошла после строки, содержащей оператор On Error, выполнение кода продолжится со следующей после вызвавшей ошибку строки.
Одним из основных отличий между JScript и VBScript является возможность указания кода, который проверяется на предмет ошибок. В VBScript, если вы «включили» обработку ошибок, она будет выполняться для всего кода или пока вы не выполните код On Error Goto 0. В JScript обрабатывается только код, включенный в блок try.
Другим отличием является то, с какого места продолжается выполнение вашей программы. В VBScript код продолжается со строки, расположенной за строкой, вызвавшей ошибку, а в JScript — со строки, следующей за блоком catch. Это означает, что строки, расположенные в блоке try за строкой, вызывавшей ошибку, не выполняются.
Помимо этого в VBScript нет синтаксиса для задания кода, который должен выполняться в случае возникновения ошибки. Вы должны вручную проверять коды, возвращаемые функциями или после выполнения какого-либо блока кода. Например:
‘ Включить обработку ошибок On Error Resume Next ‘ Очистить объект Err Err.Clear ‘ Код, который может привести к возникновению ошибки ‘ ... ‘ Есть ошибка? If Err.Number > 0 Then ‘ Обработка ошибки window.alert(Err.Description) End If
В приведенном выше примере используется встроенный объект Err, который служит для получения всей информации о произошедшей ошибке — ее кода, описания и т.п. В JScript 5.0 появился эквивалент этого объекта — объект Error. Два свойства объектов Error и Err позволяют получить информацию об ошибке.
JScript 5.0 — объект Error | VBScript 5.0 — объект Err | Описание |
---|---|---|
Error.Number | Err.Number | Код ошибки — либо внутренний код, либо код ошибки объекта Automation |
Error.Description | Err.Description | Строка, содержащая описание ошибки |
В дополнение к этому в VBScript есть метод Err.Clear для очистки содержимого объекта Err и метод Err.Raise. В Jscript таких методов нет. Собственно, в них нет необходимости, так как блок catch вызывается сразу же после возникновения исключения и объект Error всегда содержит актуальную для исключения информацию. Вместо метода Err.Raise в JScript используется оператор throw.
Рассмотрим следующий пример. Для генерации ошибок в VBScript мы задаем необходимые значения свойствам объекта Err и вызываем его метод Raise:
Sub CauseError() Err.Description = “Нестандартная ошибка” Err.Number = 1 Err.Source = “Demo.ScriptException” Err.Raise End Sub Sub RaiseError() On Error Resume Next Err.Clear CauseError If Err.Number > 0 And Err.Source == “Demo. ScriptException” Then window.alert(Err.Description) End Sub
Эквивалент данного кода на JScript будет несколько другим, потому что объект Error не содержит свойства Source, позволяющего задать источник ошибки. Вместо этого мы можем задать собственный объект, описывающий ошибку, и использовать оператор instanceof.
// Опишем наш объект-исключение function Exception(Number, Description) { this.Number = Number; this.Description = Description; } function CauseException() { // Создадим экземпляр объекта-исключения exception = new Exception(1, “Нестандартная ошибка”); // Вызовем исключение throw exception; } function RaiseException() { try { // вызовем функцию, которая приведет к исключению CauseException(); } catch (exception) { // Проверим тип исключения if (exception instanceof Exception) { window.alert(exception.Description); else { // Передадим исключение в другой обработчик throw exception; } } }
Поддержка DCOM
Поддержка DCOM в JScript реализована точно так же, как и в VBScript, за исключением того, что вы вызываете конструктор ActiveXObject. Например, следующий код:
var newObject = ActiveXObject(“ObjectName”, “\\servername”)
создаст экземпляр объекта ObjectName, расположенного на сервере servername и после этого с ним можно будет работать как с локальным объектом.
Итак, мы рассмотрели основные новинки в VBScript и JScript версии 5.0. Осталось рассказать еще о двух изменениях — об улучшении производительности и возможности кодирования программ.
Улучшение производительности
В Internet Explorer 5.0 существенно повышена производительность VBScript. Это стало возможным за счет изменения подхода к обработчикам событий. В Internet Explorer 4.0 все страницы, содержащие код на VBScript, проверялись на наличие обработчиков событий для всех элементов, и в случае отсутствия обработчика того или иного события и элемента создавался необходимый пустой код, к которому можно было присоединить обработчик уже во время выполнения программы. Все это работало медленно. В Internet Explorer 5.0 не создается пустых обработчиков и загрузка страницы происходит намного быстрее.
Кодирование программ
Существенным недостатком использования скриптовых программ является то, что любой желающий может бесплатно скопировать результаты вашей многодневной или даже многомесячной работы, — достаточно лишь выполнить команду View Source. Решение этой проблемы предлагается в Internet Explorer 5.0 — с помощью утилиты screnc.exe можно кодировать ваши скриптовые программы. Поддерживается кодирование кода в HTML- и ASP-файлах, скриптлетов и файлов для Windows Scripting Host.
Помимо сокрытия кода как такового кодирование кода позволяет поддерживать контрольные суммы: код, исправленный кем-то, кроме автора, просто перестает работать. Таким образом, любители вирусов и прочих «сюрпризов» могут не беспокоиться — подключиться в кодированные программы будет сложно.
При кодировании изменяется название скриптового языка — например, VBScript становится vbscript.encode. Так что браузеры, не поддерживающие кодирование, просто игнорируют такую программу. Более того, вам не обязательно переходить на Internet Explorer 5.0 — достаточно лишь обновить скриптовые языки.
Дополнительную информацию можно получить на Web-узле фирмы Microsoft по адресу: http://msdn.microsoft.com/scripting/
В этом номере публикуются также статьи, посвященные поддержке Document Object Model в Internet Explorer 5.0, — «Internet Explorer 5.0 и Document Object Model» и основным новинкам, представляющим интерес для программистов, — «Microsoft Internet Explorer 5.0 для разработчиков».
КомпьютерПресс 5'1999