Обычно описание языка программирования начинают с типов и структур данных, операторов и функций, а заканчивают библиотеками стандартных функций (главным образом, ввода/вывода) и опциями компилятора. В своем описании JavaScript мы двигались в обратном порядке и рассказываем об этом в конце нашего курса.
Многое из того, чему посвящены страницы данного раздела, так или иначе уже использовалось в других частях. Здесь мы соберем все вместе. Теперь основное внимание мы уделим:
- типам и структурам данных;
- операторам языка;
- функциям пользователя;
- особенностям размещения кода;
- возможности исполнения программ в фоновом режиме;
- управлению фокусом;
- вопросам безопасности.
Как видно из этого перечня, первые три позиции полностью посвящены формальному описанию языка, в то время как следующие четыре призваны показать наличие "подводных камней" при использовании JavaScript.
Типы и структуры данных
Как и любой другой язык программирования, JavaScript поддерживает встроенные типы и структуры данных. Все их многообразие подразделяется на:
- литералы и переменные;
- массивы, функции и объекты.
При этом все они делятся на встроенные и определяемые программистом. Функции и объекты рассматриваются в разделах "Функции" и "Объекты". Поэтому здесь мы остановимся на литералах, переменных и массивах.
Литералы
Литералом называют данные, которые используются в программе непосредственно. При этом под данными понимаются числа или строки текста. Все они рассматриваются в JavaScript как элементарные типы данных. Приведем примеры литералов:
числовой литерал: 10
числовой литерал: 2.310
числовой литерал: 2.3e+2
строковый литерал: 'Это строковый литерал'
строковый литерал: "Это строковый литерал"
Литералы используются в операциях присваивания значений переменным или в операциях сравнения:
var a=10;
var str = 'Строка';
if(x=='test') window.alert(x);
Два варианта строковых литералов необходимы для того, чтобы использовать вложенные строковые литералы. Вообще говоря, есть подозрение, что равноправие "..." и '...' мнимое. Если внимательно посмотреть на реализацию страниц программирования гипертекстовых ссылок (href.htm, path.htm и mouse.htm), можно заметить, что вместо прямого переназначения гипертекстовой ссылки литералом типа '...' там используется косвенное переназначение через функцию литералом "...":
...
function line(a)
{
...
window.document.main.document.links[4].href="javascript:data(0);void(0);";
...
}
...
<A HREF="javascript:line(0);void(0);">
<IMG SRC=image.gif BORDER=0>
</A>
вместо:
<A HREF="javascript:
window.document.main.document.links[4].href='javascript:data(0);void(0);';void(0);">
<IMG SRC=image.gif BORDER=0>
</A>
Это связано с особенностями реализации Netscape. Дело в том, что прямое переназначение неправильно отображает кириллицу в win32, а вот косвенное работает. Похоже, что "..." разрешает анализ информации внутри строкового литерала JavaScript-интерпретатором, а '...' — нет.
Если быть более точным, то следует сказать, что строка — это объект. У этого объекта существует великое множество методов. Строчный литерал и строчный объект — далеко не одно и то же. При применении к строчным литералам методов строчных объектов происходит преобразование первых в последние.
Переменные
Переменные в JavaScript могут быть определены назначением или при помощи оператора var:
i=10;
var i;
var i=10;
var id = window.open();
var a = new Array();
Как видно из примеров, переменные могут принимать самые разные значения, при этом тип переменной определяется контекстом.
Переменная является свойством окна. Например, мы можем открыть окно, определить в нем новую переменную и использовать ее:
wid = window.open("","test","width=200,height=100,statusbar");
wid.document.open();
wid.document.write("<HTML><HEAD>");
wid.document.write("<SCRIPT>var t;</SCRIPT>");
wid.document.write("</HEAD><BODY>");
wid.document.write("<CENTER>Новое окно<BR>");
wid.document.write("<FORM>");
wid.document.write("<INPUT TYPE=button VALUE='Закрыть окно' onClick=window.close();></FORM>");
wid.document.write("</CENTER></BODY></HTML>");
wid.document.close();
...
<A HREF="javascript:wid.t=window.prompt("Новое состояние:");wid.defaultStatus=t;wid.focus();void(0);>...</A>
Существуют ли в JavaScript различные типы переменных? По всей видимости, да. При объявлении переменной тип не указывается. Тип значения определяется контекстом, поэтому можно было бы предположить, что все переменные — одного и того же типа. Однако очевидно, что присваивание переменной значения объекта окна (window.open()) или объекта потока (setTimeout()), вызывает создание в памяти совершенно разных структур.
Поставим вопрос несколько иначе. Может ли одна и та же переменная принимать значения разных типов? Для ответа на этот вопрос рассмотрим следующий пример:
var flag=0;
var cid=null;
function clock()
{
flag=1;
d = new Date();
window.document.main.document.f0.fi1.value=
d.getHours()+":"+d.getMinutes()+":"+d.getSeconds();
cid = setTimeout("clock();",100);
}
function stop()
{
if(cid!=null)
{
clearTimeout(cid);
cid=null;
flag=0;
}
}
function wo()
{
cid = window.open("","test","width=400,height=100");
cid.document.open();
cid.document.write("<HTML><HEAD></HEAD><BODY><CENTER>");
cid.document.write("<FORM><INPUT TYPE=button
onClick='window.close();' value='Закрыть окно'></FORM></CENTER>");
cid.document.write("</BODY></HTML>");
cid.document.close();
cid.focus();
}
...
<FORM NAME=f0>
<INPUT NAME=fi1 SIZE=8 MAXLENGTH=8>
<INPUT TYPE=button VALUE="Часы(start/stop)" onClick="if(flag==0)clock();else stop();">
<INPUT TYPE=button VALUE="Окно" onClick="wo();">
</FORM>
Можно в любом порядке нажимать на кнопки формы, и все будет работать правильно. При этом переменная cid используется и как идентификатор потока, и как идентификатор окна. Это означает, что JavaScript все-таки поддерживает полиморфизм, т.е. существует два разных объекта с одинаковыми именами, и система в них не путается.
|