Функции и объекты
Коллекция — это структура данных JavaScript, похожая на массив. Отличие коллекции от массивов заключается в том, что массивы программист создает сам в коде программы и заполняет их данными; коллекции же создаются браузером и «населяются» объектами, связанными с элементами Web-страницы. Коллекцию можно рассматривать как другой, зачастую более удобный способ доступа к объектам Web-страницы.
Например, если на странице имеются формы с именами f , g5 и h32 , то у объекта document есть соответствующие свойства-объекты document.f , document.g5 и т.д. Но кроме того, у объекта document есть свойство forms , являющееся коллекцией (массивом) всех форм, и значит, к тем же самым объектам форм можно обратиться как document.forms[0] , document.forms[1] и т.д. Это бывает удобным, когда необходимо выполнить какие-то действия со всеми объектами форм на данной странице. Указывая свойства того или иного объекта, мы обычно пишем коллекции со скобками: forms[] , images[] , frames [] , чтобы подчеркнуть, что это не обычные свойства, а коллекции.
Нумеруются элементы коллекции, начиная с нуля, в порядке их появления в исходном HTML-файле. Доступ к элементам коллекций осуществляется либо по индексу (в круглых или квадратных скобках), либо по имени (тоже в круглых или квадратных скобках, либо через точку), например:
window.document.forms[4] // 5-я форма на странице window.document.forms(4) // равносильно предыдущему window.document.forms['mf'] // форма с именем 'mf' window.document.forms('mf') // равносильно предыдущему window.document.forms.mf // равносильно предыдущему window.document.mf // равносильно предыдущему
Способы в 3-4 строчках удобны, когда имя элемента коллекции хранится в качестве значения переменной. Например, если мы задали var w=»mf» , то мы можем обратиться к форме с именем » mf » как window.document.forms[w] . Именно так мы поступили выше в разделе про оператор for. in , когда выписывали список всех свойств объекта document .
Как и у обычных массивов, у коллекций есть свойство length , которое позволяет узнать количество элементов в коллекции. Например, document.images. length .
Перечислим основные коллекции в объектной модели документа .
Коллекция | Описание |
---|---|
window. frames [] | Все фреймы — т.е. объекты, отвечающие контейнерам FRAME > |
document.all[] | Все объекты, отвечающие контейнерам внутри контейнера |
document. anchors [] | Все якоря — т.е. объекты, отвечающие контейнерам |
document. applets [] | Все апплеты — т.е. объекты, отвечающие контейнерам APPLET > |
document.embeds[] | Все вложения — т.е. объекты, отвечающие контейнерам |
document.forms[] | Все формы — т.е. объекты, отвечающие контейнерам |
document.images[] | Все картинки — т.е. объекты, отвечающие контейнерам IMG > |
document.links[] | Все ссылки — т.е. объекты, отвечающие контейнерам HREF =». «> и AREA HREF =». «> |
document.f. elements [] | Все элементы формы с именем f — т.е. объекты, отвечающие контейнерам и |
document.f.s.options[] | Все опции (контейнеры ) в контейнере в форме |
navigator .mimeTypes[] | Все типы MIME , поддерживаемые браузером (список см. на сайте IANA) |
function_name. arguments [] | Все аргументы, переданные функции function_name() при вызове |
Cвойства
Многие HTML-контейнеры имеют атрибуты . Как мы уже знаем, каждому контейнеру соответствует объект. При этом соответствии атрибутам отвечают свойства объекта. Соответствие между атрибутами HTML-контейнеров и свойствами DOM -объектов не всегда прямое. Обычно каждому атрибуту отвечает некоторое свойство объекта. Но, во-первых, название этого свойства не всегда легко угадать по названию атрибута, а во-вторых, у объекта могут быть свойства, не имеющие аналогов среди атрибутов. Кроме того, как мы знаем, атрибуты являются регистро-независимыми, как и весь язык HTML, тогда как свойства объектов нужно писать в точно определенном регистре символов.
Например, контейнер якоря . имеет атрибут HREF , который превращает его в гипертекстовую ссылку:
Данной гиперссылке соответствует объект (класса URL ) — document.links[0] , если предполагать, что это первая ссылка в нашем документе. Тогда атрибуту HREF будет соответствовать свойство href этого объекта. К свойству объекта можно обращаться с помощью точечной нотации : объект.свойство . Например, чтобы изменить адрес, на который указывает эта ссылка, мы можем написать:
document.links[0].href='http://ya.ru/';
К свойствам можно также обращаться с помощью скобочной нотации : объект[‘свойство’] . В нашем примере:
document.links[0]['href']='http://ya.ru/';
У объектов, отвечающих гиперссылкам, есть также свойства, не имеющие аналогов среди атрибутов. Например, свойство document.links[0]. protocol в нашем примере будет равно «http:» и т.д. Полный перечень свойств объектов класса URL Вы найдете в «Программируем гипертекстовые переходы» .
Методы
В терминологии JavaScript методы объекта определяют функции, с помощью которых выполняются действия с этим объектом, например, изменение его свойств , отображения их на web-странице, отправка данных на сервер, перезагрузка страницы и т.п.
Например, если у нас есть ссылка HREF keyword181″> intuit .ru/»> intuit (будем считать, она первая в нашем документе), то у соответствующего ей объекта document.links[0] есть метод click () . Его вызов в любом месте JavaScript-программы равносилен тому, как если бы пользователь кликнул по ссылке, что демонстрирует пример:
При открытии такой страницы пользователь сразу будет перенаправлен на сайт ИНТУИТ. Обратите внимание, что скрипт написан после ссылки. Если бы мы написали его до ссылки, то поскольку в этот момент ссылки (а значит и объекта) еще не существует, браузер выдал бы сообщение об ошибке.
Некоторые методы могут применяться неявно. Для всех объектов определен метод преобразования в строку символов : toString() . Например, при сложении числа и строки число будет преобразовано в строку:
"25"+5 = "25"+(5).toString() = "25"+"5" = "255"
Аналогично, если обратиться к объекту window. location (рассматриваемом в следующей лекции) в строковом контексте, скажем, внутри вызова document.write() , то неявно будет выполнено это преобразование, и программист этого не заметит, как если бы он распечатывал не объект, а строку:
Тот же эффект можно наблюдать для встроенных объектов типа Date :
Результат исполнения получите сами.
События
Кроме методов и свойств, объекты характеризуются событиями . Собственно, суть программирования на JavaScript заключается в написании обработчиков этих событий. Например, с объектом типа button (контейнер INPUT типа button — «кнопка») может происходить событие Click , т.е. пользователь может нажать на кнопку. Для этого атрибуты контейнера INPUT расширены атрибутом обработки этого события — onClick . В качестве значения этого атрибута указывается программа обработки события , которую должен написать на JavaScript автор HTML-документа:
Обработчики событий указываются в специально созданных для этого атрибутах у тех контейнеров, с которыми эти события связаны. Например, контейнер BODY определяет свойства всего документа, поэтому обработчик события «завершена загрузка всего документа» указывается в этом контейнере как значение атрибута onLoad .
Примеры событий: нажатие пользователем кнопки в форме, установка фокуса в поле формы или увод фокуса из нее, изменение введенного в поле значения, нажатие кнопки мыши, отпускание кнопки мыши, щелчок кнопкой мыши на объекте (ссылке, поле, кнопке, изображении и т.п.), двойной щелчок кнопкой мыши на объекте, перемещение указателя мыши, выделение текста в поле ввода или на странице и другие. Однако, некоторые изменения, происходящие на странице, не генерируют никаких событий; например: изменение значения в поле ввода не пользователем, а скриптом, изменение фона документа, изменение (скриптом) значения атрибута HREF ссылки, а также изменение большинства других атрибутов HTML-контейнеров. Обо всех важных событиях и об их «перехвате» будет рассказываться далее в соответствующих лекциях.
Разные браузеры могут вести себя по-разному при возникновении событий. Рассмотрим следующий пример, позволяющий определить, в каком порядке вызываются обработчики событий при клике либо двойном клике мыши на ссылке или кнопке:
Проверьте работу этой странички в Вашем браузере. При одиночном клике на ссылке или кнопке события возникают в порядке: MouseDown , MouseUp , Click , что логично. При двойном же клике последовательность происходящих событий в разных браузерах разная:
в браузере Mozilla Firefox 3.08: MouseDown, MouseUp, Click, MouseDown, MouseUp, Click, DblClick в браузере Internet Explorer 7.0: MouseDown, MouseUp, Click, MouseUp, DblClick
Как видим, в Mozilla Firefox последовательность событий более логична — она состоит из двух последовательностей событий, отвечающих одиночному клику, и далее событие двойного клика. Вы можете написать чуть более изощренный скрипт, показывающий, что в IE7 действительно не происходит второго события Click при двойном клике мышью.
В чем отличия коллекции от массива?
Алексей Тен, Array, <>, Map, WeakMap, Set, WeakSet, NodeList (DOMSettableTokenList, DOMStringList, DOMTokenList, HTMLDataListElement, HTMLUListElement, HTMLOListElement, HTMLDListElement, RadioNodeList), SVG. List
iamevg_, у коллекций — только length.
У массивов — весьма много, начиная с forEach.
Прототипы: NodeListPrototype и Array.prototype соответственно.
KorniloFF, Во первых «NodeListPrototype» не существует. Есть NodeList.prototype.
Во вторых, у коллекции узлов есть не только length. Также есть методы, «entries», «forEach», «item», «keys», «values». Также она наследует методы и свойства еще и от Object + порядка 6-7 методов.
В третьих массив тоже является коллекцией.
В четвертых вы сравниваете молоток с инструментом.
iamevg_, честно говоря, не знал. Всю жизнь пользую конструкцию
[].forEach.call(Collection, fn);
Сейчас посмотрел — да, есть и у коллекций. А в какой версии языка появилась вся эта прелесть?
P.S. NodeListPrototype скопировал из консоли Мозиллы.
Прошу прощение ТС невольное введение в заблуждение.
Ну уже загуглить не могут! Ссылка
Сейчас только узнал, что они существуют, но в целом по опыту могу сказать, это попытка сделать разграничение коллекций на типы как в нормальных языках. Т.к. разные типы коллекции потребляют разное количество памяти и имеют те или иные полезные свойства, методы.
Больше времени тратишь на различные обработчики, повышается ЧСВ. Можно и дальше использовать обычный массив.
А как при помощи массива реализовать понастоящему приватное свойство класса ? А WeakMap это позволяет на ура.
let thumbnails = new WeakMap(); function getThumbnail(image) < let thumbnail = thumbnails.get(image); if (!thumbnail) < thumbnail = createThumbnail(image); thumbnails.set(image, thumbnail); >return thumbnail; >
let thumbnails = new WeakMap(); class PostImage < constructor(image) < thumbnails.set(this, createThumbnail(image)); this.image = image; >someMethodForThumbnail() < let thumbnail = thumbnails.get(this) return doSomeThing(thumbnail); >>
iamevg_, Ну тоесть вам в голову кусок кода где приватность делается с помощью ВикМапов в голову не приходит ? И не понимаете почему ВикМапы а не замыкания ? Пример выше поправил.