У любого типа данных JavaScript существует объектовая "обертка" (wrapper), которая позволяет применять методы типов данных к переменным и литералам, а также получать значения их свойств. Например, длина строки символов определяется свойством length. Аналогичная "обертка" есть и у функций - это класс объектов Function.
Например, увидеть значение функции можно не только при помощи методаvalueOf(), но и используя метод toString():
function f(x,y){ return x-y;}document.write(f.toString());
Результат распечатки:
function f(x,y) { return x-y; }
Свойства же функции как объекта доступны программисту только тогда, когда они вызываются внутри этой функции. Наиболее часто используемыми свойствами являются: массив (коллекция) аргументов функции ( arguments[] ), его длина ( length ), имя функции, вызвавшей данную функцию ( caller ), ипрототип ( prototype ).
Рассмотрим пример использования списка аргументов функции и его длины:
function my_sort(){ a = new Array(my_sort.arguments.length); for(i=0;i<my_sort.arguments.length;i++) a[i] = my_sort.arguments[i]; return a.sort();} b = my_sort(9,5,7,3,2);document.write(b);// Будет выдано: 2,3,5,7,9
Чтобы узнать, какая функция вызвала данную функцию, используется свойствоcaller. Возвращаемое ею значение имеет тип function. Пример:
function s(){ document.write(s.caller+"<BR>"); } function M(){ s(); return 5; } function N(){ s(); return 7; } M(); N();
Еще одним свойством объекта класса Function является prototype. Но это - общее свойство всех объектов, не только функций, поэтому и обсуждать его мы будем в следующем разделе в контексте типа данных Object. Упомянем только о конструкторе объекта класса Function:
f = new Function(arg_1,...,arg_n, body)
Здесь f - это объект класса Function (его можно использовать как обычную функцию), arg_1, ..., arg_n - аргументы функции f, а body - строка, задающая тело функции f.
Данный конструктор можно использовать, например, для описания функций, которые назначают или переопределяют методы объектов. Здесь мы вплотную подошли к вопросу конструирования объектов. Дело в том, что переменные внутри функции можно рассматривать в качестве ее свойств, а функции - в качестве методов:
function Rectangle(a,b,c,d){this.x0 = a;this.y0 = b;this.x1 = c;this.y1 = d; this.area = new Function( "return Math.abs((this.x1-this.x0)*(this.y1-this.y0))");} r = new Rectangle(0,0,30,50); document.write("Площадь: "+r.area()); // Будет выведено:// Площадь: 1500
Обратите внимание еще на одну особенность - ключевое слово this. Оно позволяет сослаться на текущий объект, в рамках которого происходит исполнение JavaScript-кода. В данном случае это объект класса Rectangle.
Объекты
Объект - это главный тип данныхJavaScript. Любой другой тип данных имеет объектовую "обертку" (wrapper). Это означает, что прежде чем можно будет получить доступ к значению переменной того или иного типа, происходит конвертирование переменной в объект, и только после этого выполняются действия над значением. Тип данных Object сам определяет объекты.
В сценарии JavaScript могут использоваться объекты нескольких видов:
клиентские объекты, входящие в модель DOM, т.е. отвечающие тому, что содержится или происходит на Web-странице в окне браузера. Они создаются браузером при разборе (парсинге) HTML-страницы. Примеры:window, document, location,navigator и т.п.
серверные объекты, отвечающие за взаимодействие клиент-сервер. Примеры: Server, Project, Client, File и т.п. Серверные объекты в этом курсе рассматриваться не будут.
встроенные объекты. Они представляют собой различные типы данных, свойства, методы, присущие самому языку JavaScript, независимо от содержимого HTML-страницы. Примеры: встроенные классы объектов Array,String, Date, Number, Function, Boolean, а также встроенный объект Math.
пользовательские объекты. Они создаются программистом в процессе написания сценария с использованием конструкторов типа объектов (класса). Например, можно создать свои классы Cat и Dog. Создание и использование таких объектов будет рассмотрено далее в этой лекции.
Операторы работы с объектами
for ... in ...
Оператор for(переменная in объект) позволяет "пробежаться" по свойствамобъекта. Рассмотрим пример (об объекте document см. ниже):
for(v in document) document.write("document."+v+" = <B>"+ document[v]+"</B><BR>"); Результатом работы этого скрипта будет длинный список свойств объектаdocument, мы приведем лишь его начало (полностью получите его самостоятельно):
alinkColor = #0000ffbgColor = #ffffffmimeType = HTML DocumentdefaultCharset = windows-1251lastModified = 07/16/2002 21:22:53onclick = nulllinks = [object]... Примечание Попробуйте запустить этот скрипт в разных браузерах - и Вы увидите, что набор свойств у объекта document различный в различных браузерах. Аналогичная ситуация со многими объектами модели DOM, о которой пойдет речь ниже. Именно поэтому приходится постоянно заботиться о так называемой кроссбраузерной совместимости при программировании динамических HTML-документов.
with
Оператор with задает объект по умолчанию для блока операторов, определенных в его теле. Синтаксис его таков:
with (объект) оператор; Все встречающиеся в теле этого оператора свойства и методы должны быть либо записанными полностью, либо они будут считаться свойствами и методами объекта, указанного в операторе with. Например, если в документе есть форма с именем anketa, а в ней есть поля ввода с именами age и speciality, то мы можем воспользоваться оператором with для сокращения записи:
with (document.anketa){ age.value=35; speciality.value='программист'; window.alert(length); submit();} Здесь age.value есть сокращенное обращение к document.anketa.age.value,length есть краткая запись свойства document.anketa.length (означающего число полей в форме), submit() есть краткая запись методаdocument.anketa.submit() (отсылающего введенные в форму данные на сервер), тогда как метод window.alert() записан полностью и не относится к объекту document.anketa.
Оператором with полезно пользоваться при работе с объектом Math, используемым для доступа к математическим функциям и константам. Например, внутри тела оператора with(Math) можно смело писать: sin(f)*cos(h+PI/2) ; без оператора with пришлось бы указывать Math три раза:Math.sin(f)*Math.cos(h+Math.PI/2)
Клиентские объекты
Для создания механизма управления страницами на клиентской стороне используется объектная модель документа (DOM - Document Object Model). Суть модели в том, что каждому HTML-контейнеру соответствует объект, который характеризуется тройкой:
свойства
методы
события
Объектную модель можно представить как способ связи между страницами и браузером. Объектная модель документа - это представление объектов, ихметодов, свойств и событий, которые присутствуют и происходят в программном обеспечении браузера, в виде, удобном для работы с ними из кода HTML и исходного текста сценария на странице. Мы можем с ее помощью сообщать наши пожелания браузеру и далее - посетителю страницы. Браузер выполнит наши команды и соответственно изменит страницу на экране.
Объекты с одинаковым набором свойств, методов и событий объединяются вклассы однотипных объектов. Классы - это описания возможных объектов . Сами объекты появляются только после загрузки документа браузером или как результат работы программы. Об этом нужно всегда помнить, чтобы не обратиться к объекту, которого нет.
Иерархия классов DOM
Объектно-ориентированный язык программирования предполагает наличиеиерархии классов объектов. В JavaScript такая иерархия начинается с класса объектов window, т.е. каждый объект приписан к тому или иному окну. Для обращения к любому объекту или его свойству указывают полное или частичное имя этого объекта или свойства объекта, начиная с имени объекта, старшего в иерархии, в который входит данный объект:
Рис. 3.1. Иерархия объектов DOM (фрагмент)
Сразу оговоримся, что приведенная нами схема объектной модели верна для Netscape Navigator версии 4 и выше, а также для Microsoft Internet Explorer версии 4 и выше. Еще раз отметим, что объектные модели у Internet Explorer и Netscape Navigator совершенно разные, а приведенная схема составлена на основе их общей части.
Вообще говоря, JavaScript не является классическим объектным языком (его еще называют облегченным объектным языком). В нем нет наследования и полиморфизма. Имеется лишь отношение "объект A содержит объект B " (которое и проиллюстрировано на рис. 3.1). Оно не является иерархией классов в буквальном смысле. Действительно, нахождение класса window в этой иерархии выше класса history не означает, что всякий объект типа historyявляется объектом типа window и наследует все его свойства и методы, как это понималось бы в стандартных объектно-ориентированных языках. В JavaScript же это отношение означает лишь то, что объект history является свойствомобъекта window, а значит, чтобы получить к нему доступ, нужно воспользоваться "точечной нотацией": window.history.
У объектов DOM некоторые свойства обязательно присутствуют, тогда как наличие других зависит от Web-страницы. Например, объект window всегда имеет в качестве своих свойств объекты location и history, т.е. это обязательные свойства. Если HTML-страница содержит контейнер <BODY>, то у объекта window будет присутствовать в качестве свойства объект document. Если HTML-страница содержит контейнер <FRAMESET> со вложенными в него контейнерами <FRAME>, то у объекта window будут присутствовать в качестве свойств имена фреймов, например window.f1. Последние, как мы увидим в будущих лекциях, сами являются объектами класса window, и для них в свою очередь справедливо все вышесказанное.
Примечание. Строго говоря, каждый браузер, будь то Internet Explorer, Netscape Navigator или Opera, имеет свою объектную модель. Объектные модели разных браузеров (и даже разные версии одного) отличаются друг от друга, но имеют принципиально одинаковую структуру. Поэтому нет смысла останавливаться на каждой из них по отдельности. Мы будем рассматривать общий подход применительно ко всем браузерам, иногда, конечно, заостряя внимание на различиях между ними.