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. Каждый имеет свои достоинства и недостатки, но какой именно способ выбрать для работы - решать вам.

Мнения (7)

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

  • Miscђka

    22 ноября 2007 г.14:10

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

    alert(MyObject.getName);

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

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

  • Iwannt

    28 января 2008 г.18:47

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

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

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

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

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

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

  • Дин автор

    28 января 2008 г.18:56

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

  • Iwannt

    29 января 2008 г.03:15

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

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

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

  • Алик Кириллович

    12 июня 2008 г.22:57

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

    Т.е. Не так:

    MyObject = {

       id : 1;

       name : «Sample»;

       boolval : true;

       …

    }

    А вот так:

    MyObject = {

       id : 1,

       name : «Sample»,

       boolval : true,

       …

    }

  • Дин

    12 июня 2008 г.23:21

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

  • Yrox

    30 сентября 2009 г.15:59

    Спасибо большое за инфу, очень пригодилась!!!

Я тоже знаю!

Для обращения к человеку используйте символ @, после которого следует имя того, к кому обращаетесь (пробелы заменяются на знак подчёркивания). Если вам интересно, можете подписаться на комментарии по RSS или по эл. почте. Ведите себя достойно, вы же не роботы, правда?

Вы можете использовать следующие XHTML-элементы в разметке комментария: strong, em, span[class=crossline], a[href=uri], code[type=язык], blockquote, ul и ol. В качестве языка кода может быть указан, например, javascript или css.