Регистрация    Вход    Форум    Поиск    FAQ

  •  Новости
  • Beeline + Twitter = чирикай через SMS!

    Beeline + Twitter = чирикай через SMS! На первой картинке обозначены команды, при помощи которых через SMS Вы сможете кого-либо зафолловить или же отписаться, ретвитнуть чей-либо пост или же написать личное сообщение.

    Open Graph Protocol. От создателей Facebook

    Open Graph Protocol. От создателей Facebook Разбираясь с Facebook API, случайно наткнулся на другую интересную разработку от этих людей.

    Глобальное ускорение Wordpress

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




  •  Часы


  •  Поиск

Optimaze » Программирование » Объектно-ориентированное программирование в JavaScript




Объектно-ориентированное программирование в JavaScript

  1. Объекты в JavaScript
  2. Конструкторы
  3. Прототип объекта


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

 

Объекты в JavaScript

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

 

  • var greeter = {
  •   name: ‘John Smith’,
  •   greet: function() {
  •     alert(‘Hello, ‘ + this. name);
  •   }
  • };
  • greeter. greet();
  • // Поприветствуем кого-нибудь еще
  • greeter. name = ‘Alex’;
  • greeter. greet();

 

Говоря об объекте, можно провести аналогию с хэшем: объект, как и хэш, является набором ключей (атрибутов) и соответствующих им значений. JavaScript даже поддерживает альтернативный синтаксис для доступа к атрибутам объекта – например, последние 2 строки предыдущего примера можно было записать так:

 

greeter[‘name’] = ‘Mike Lapshin’;

greeter[‘greet’]();

 

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

var attrName = ‘name’;

greeter[attrName] = ‘Alex’;

При присвоении значения несуществующему атрибуту этот атрибут будет автоматически создан:

 

greeter. newAttribute = ‘New attribute value’;

alert(greeter. newAttribute);

Конструкторы

Для создания объектов в JavaScript, как и в других языках, существуют конструкторы. Конструктор в JavaScript – это глобальная функция, вызываемая с помощью оператора new. Внутри этой функции программист может инициализировать атрибуты объекта, обращаясь к ним через ключевое слово this:

 

  • // Конструктор Greeter
  • function Greeter(name) {
  •   this. name = name;
  •  
  •   // Точно так же можно создать метод
  •   this. greet = function() {
  •     alert(‘Hello, ‘ + this. name);
  •   };
  • }
  •  
  • // Создаем объекты
  • var johnGreeter = new Greeter(‘John’);
  • var alexGreeter = new Greeter(‘Alex’);
  •  
  • alexGreeter. greet(); // Hello, Alex
  • johnGreeter. greet();  // Hello, John

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

 

  • johnGreeter. greet = function() {
  •   alert(‘Batito de coco, ‘ + this. name);
  • };
  •  
  • johnGreeter. greet(); // Batito de coco, John
  • alexGreeter. greet(); // Hello, Alex

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

 

Мы видим, что метод greet() объекта alexGreeter остался неизменным - что, по-сути, логично. Дело в том, что если метод инициализируется в конструкторе, то при создании объекта он каждый раз будет создаваться заново (то есть копироваться). Обратная сторона медали в этом случае – память. Если создать 20000 объектов Greeter, то абсолютно одинаковый у всех экземпляров метод Greeter. greet() будет создан в памяти 20000 раз.

 

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

 

Прототип объекта

Для решения этой проблемы в JavaScript существует специальное средство, называемое прототипом. Метод, инициализированный в прототипе, создается только один раз и разделяется между всеми объектами, использующими этот прототип. Таким образом, наш пример можно переписать следующим образом:

 

  • // Конструктор Greeter
  • function Greeter(name) {
  •   this. name = name;
  • }
  •  
  • Greeter. prototype. greet = function() {
  •   alert(‘Hello, ‘ + this. name);
  • }
  •  
  • // Создаем объекты
  • var johnGreeter = new Greeter(‘John’);
  • var alexGreeter = new Greeter(‘Alex’);
  •  
  • alexGreeter. greet(); // Hello, Alex
  • johnGreeter. greet();  // Hello, John

Прототип, как и все остальное в JavaScript, является объектом. Доступ к нему можно получить через ИмяКласса. prototype. Мы можем переписать 6-ю строку примера следующим образом:

 

Greeter. prototype[‘greet’] = function() {

И это будет работать. Вообще, нужно объяснить принцип взаимодействия объекта с его прототипом. Когда интерпретатор JavaScript встречает обращение к атрибуту объекта (через this внутри класса или через переменную извне), он сперва проверяет, определен ли этот атрибут в самом объекте.

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

 

На самом деле атрибута greet нет ни у объекта alexGreeter, ни у объекта johnGreeter. У этих объектов есть только атрибут name. Но интерпретатор при обращении к методу greet находит этот метод в прототипе.

 

Чтобы проиллюстрировать вышесказаное, попробуем еще раз переопределить метод greet. Сперва мы переопределим его у конкретного объекта, а потом у прототипа объекта.

 

alexGreeter. greet = function() {

  alert(‘Howdy, ‘ + this. name);

}

 

// Теперь у объекта alexGreeter

// есть атрибут greet, и интерпретатор

// при обращении к нему будет использовать

// атрибут объекта, а не атрибут прототипа

alexGreeter. greet();  // Howdy, Alex

 

// У объекта johnGreeter атрибута greet

// нет, поэтому будет использована общая версия

// этого метода из прототипа класса Greeter

johnGreeter. greet(); // Hello, John

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

 

  • Greeter. prototype. greet = function() {
  •   alert(‘What a wonderful day, ‘ + this. name);
  • }
  •  
  • alexGreeter. greet(); // What a wonderful day, Alex
  • johnGreeter. greet();  // What a wonderful day, John

 

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



Рейтинг: 4.7/5, основан на 25 голосах.


Нравится



Вернутся назад


   

Вам будет интересно:

Excelsior Jet Roadmap

Компания Excelsior представила предварительный roadmap выпуска своих продуктов.

Верстка DIVaми в DreamWeaver

Когда мы расматривали верстку таблицами, мы резали макет на картинки, для дивной верстки надо тоже порезаные картинки.

Hibernate 3. 1. 3 out

Эта версия, в основном, содержит исправления ранее найденных ошибок, самой неприятной из которых, по моему мнению, является отсутствие отложенной инициализации many-to-one ассоциации в ветке 3.1.

Игры на HTML5 Canvas для чайников – часть I

Опять же, интересно будет скорее новичкам, которые игр никогда не разрабатывали.



  •  Публикации


8 методов раскрутки своего форума с нуля

8 методов раскрутки своего форума с нуля Итак, у вас имеется свой собственный форум, но его никто не посещает? Мы готовы помочь вам справиться с этой нелегкой проблемой.

Как привлекать посетителей на проект

Как привлекать посетителей на проект Данная статья в основном рассчитана на тех, кто самостоятельно занимается продвижением своего проекта.

Про MySQL, серверы и PayPal

Про MySQL, серверы и PayPal Проклял все настройки кодировок, проклял DirectAdmin и еле-еле нашел то место где располагается и задается общий пароль для ...

Реклама в Твиттере. Как подать свой продукт

Реклама в Твиттере. Как подать свой продукт Твиттер уже давно стал из нового web 2. 0 сервиса рекламной площадкой с огромным количеством потенциальных пользователей ...

Пока блог на локалхосте

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

Авторитет блоггера притягивает

Авторитет блоггера притягивает Долго не знал с чего начать данную статью. Статья что-то типа мыслей вслух и философии.