Javascript и ООП

13 сентября 2007 года, 19:47

Javascript, помимо стандартных возможностей, предоставляет массу способов использовать объектно-ориентированное программирование. В Javascript вы можете создавать объекты или псевдообъекты. Для этого существуют следующие способы:

  • Оператор new
  • Литеральная нотация
  • Конструкторы объектов
  • Прототипы
  • Ассоциативные массивы

Используем оператор new

Это, наверное, самый легкий способ создания объекта. Вы просто создаете имя объекта и приравниваете его к новому объекту Javascript.

//Создаем наш объект var MyObject = new Object(); //Переменные MyObject.id = 5; //Числовая переменная MyObject.name = "Sample"; //Строковая переменная //Функции MyObject.getName = function() { return this.name; }

Минус данного способа заключается в том, что вы можете работать только с одним вновь созданным объектом.
//Используем наш объект alert(MyObject.getName());

Литеральная нотация

Литеральная нотация является несколько непривычным способом определения новых объектов, но достаточно легким для понимания. Литеральная нотация работает в версии Javascript 1.2 и выше.

//Создаем наш объект с использованием литеральной нотации MyObject = { id : 1, name : "Sample", boolval : true, getName : function() { return this.name; } }

Как видите, это довольно просто.

Объект = { имя_переменной : содержание переменной; ... }

Использовать это легко.

alert(MyObject.getName);
Конструкторы объектов

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

function MyObject(id, name) { }

Если проводить параллели с ООП, то это - функция-конструтор. С помощью неё мы и будем создавать наш объект.

var MyFirstObjectInstance = new MyObject(5,"Sample"); var MySecondObjectInstace = new MyObject(12,"Othe Sample");

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

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

function MyObject(id, name) { //Значения переданные пользователем this._id = id; this._name = name; //Значение по умолчанию this.defaultvalue = "MyDefaultValue"; }

Аналогичным образом мы можем создавать и функции.

function MyObject(id,name) { this._id = id; this._name = name; this.defaultvalue = "MyDefaultValue"; //Получение текущего значения this.getDefaultValue = function() { return this.defaultvalue; } //Установка нового значения this.setDefaultValue = function(newvalue) { this.defaultvalue = newvalue; } //Произвольная функция this.sum = function(a, b) { return (a+b); } }

Я считаю, что это один из самых мощнейших механизмов Javascript.

Использование прототипов

Прототипы в Javascript`е появились с версии 1.1. С помощью прототипов можно добавлять новые свойства и параметры к уже существующим объектам. В прототипах можно провести некоторую аналогию с наследованием в ООП: создается иерархия, или слои.

Объект <= Класс <= Экземпляр класса

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

Создание объекта здесь ничем не отличается от аналогичного процесса при создании объекта с помощью конструкторов.

function MyObject(id, name) { //Устанавливаем значения this._id = id; this._name = name; }

Если вдруг мы захотим создать новое свойство для объекта MyObject, то сделать это можно будет следующим образом:

var MyInstance = new MyObject(5,"some value"); MyInstance.newproperty = true;

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

var MyInstance = new MyObject(5,"some value"); MyInstance.prototype.newproperty = false; MyInstance.newproperty = true;

Это не является лучшим решением использования прототипов - это просто пример. Почему это не является лучшим решением? Потому что код будет трудно сопровождать, если свойства объектов не как положено (в самом объекте), а в произвольном месте скрипта.

Свойствам, созданным через прототипы, можно задавать значения по умолчанию. Впоследствии их можно будет перезаписать (это было показано в предыдущем примере).

Как и следовало ожидать, помимо свойств можно создавать и методы. Вот простой пример того, как это сделать.

//Используем наш [b]объект[/b], а не [b]экземпляр[/b]. MyObject.prototype.getId = function() { return this._id; }

Механизм прототипов мощен не только по вышеперечисленным возможностям, но и потому, что можно улучшать собственные объекты Javascript, такие как String, Array, и другие. Приведу простой пример:

//Функция получения количества слов в строке function getWordsCount() { return this.split(" ").length; } //Назначаем функцию прототипу String.prototype.getWordsCount = getWordsCount; //Пример использования: var mystring = "My Test String"; alert(mystring.getWordsCount()); //Должно вывести число 3

Ассоциативные массивы

Помимо стандартных методов, существуют и достаточно экзотические, такие как создание ассоциативных массивов. Это будет полезно для упорядочивания большого числа однотипных объектов.

var MyObject = new Array(); MyObject["id"] = 5; MyObject["name"] = "SampleName";

Итак, мы рассмотрели способы создания объектов с помощью Javascript. Каждый имеет свои достоинства и недостатки, но какой именно способ выбрать для работы - решать вам.

Мнения (6)

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

  • Miscђka

    22 ноября 200714:10 Литеральная нотация
    ...
    Использовать это легко.

    alert(MyObject.getName);

    у функции пропущены скобки.

    Спасибо за разъяснение прототипов. Я на буржуйском читал, тонкостей некоторых не уловил.
  • Iwannt

    28 января 200818:47 Ок! Вы изложили традиционно-классовый подход к программированию на JavaScript.

    Однако, несмотря на то, что работа с прототипами в JS реализованна не совсем интуитивно :), это все же прототипный язык и, следовательно, классов в нем по определению быть не может.

    Использование функций-конструкторов в данном случае - это обходной путь, используемый для того, чтобы привнести широко распространеный и, следовательно, более понятный классовый подход.

    В статье Дугласа Крокфорда "Прототипное наследование в JavaScript" (http://javascript.crockford.com/prototypal.html) приводится пример простой функции, с помощью которой процесс клонирования прототипа можно сделать более удобным.

    Я немного усовершенствовал эту функцию на своем сайте и назвал ее CIC-function. :) (http://iwannt.nm.ru/cic.html).

    Использование литеральной нотации для определения объектов вкупе с cic-функцией позволит писать код, похожий на код Self (отец прототипного программирования).
  • Дин

    28 января 200818:56 Да, это действительно красиво. Спасибо за хорошую ссылку Вам.
    А почему бы Вам не привнести подобный метод в массы? Наверняка, и у него найдутся свои поклонники. Или это уже сделано?
  • Iwannt

    29 января 200803:15 "А почему бы Вам не привнести подобный метод в массы?" - потому что Крокфорд уже привнес его! :)

    На самом деле, я сейчас занимаюсь одним сайтом, который вскоре будет переделан (буквально redesigned :)). Я собираюсь накидать простенькую js-библиотеку для новой версии сайта, которая как раз и будет использовать прототипный подход в изложении Крокфорда.

    Если это будет что-то стоящее, то, возможно, библиотека появится на Google Code :)
  • Алик Кириллович

    12 июня 200822:57

    Опечатка в примере литеральной (JSON) нотации: свойства должны разделяться не точкой с запятой, а запятой.

    Т.е. Не так:

    MyObject = {

       id : 1;

       name : «Sample»;

       boolval : true;

       …

    }

    А вот так:

    MyObject = {

       id : 1,

       name : «Sample»,

       boolval : true,

       …

    }

  • Дин

    12 июня 200823:21

    Спасибо большое за исправление!

Я тоже знаю!

Вы можете тоже написать собственный комментарий. Если хотите к кому-то обратиться, используйте символ @, после которого не забудьте написать имя того, к кому обращаетесь. Не забывайте про существование XHTML-элементов, с помощью которых вы можете оформить ваш комментарий как вам угодно. И, да: ведите себя достойно, вы же не роботы, правда? Если вам интересно, можете подписаться на комментарии по RSS.