Сокращаем JavaScript код

1 октября, 2008
javascript call

Эта заметка о приеме, который позволяет сократить количество JavaScript кода и сделать его легко читаемым.

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

Чтобы не быть голословным, приведу пример такого класса.

  1. function Fruits() {
  2.     this.apples = 10;
  3.     this.oranges = 20;
  4.     this.pears = 30;
  5. }
  6.  
  7. Fruits.prototype.get_apples = function() {
  8.     return this.apples;
  9. }
  10.  
  11. Fruits.prototype.get_oranges = function() {
  12.     return this.oranges;
  13. }
  14.  
  15. Fruits.prototype.get_pears = function() {
  16.     return this.pears;
  17. }

Создать экземпляр этого класса можно так:

  1. var f = new Fruits;

Предположим, что пользователь видит перед собой форму с выпадающим списком, в котором может выбрать название фрукта.

Нам нужно написать функцию-обработчик, которая будет возвращать количество фруктов.

Для этого мы определяем, какой пункт списка (фрукт) выбрал пользователь, и сохраняем его название в переменной curFruit. Теперь нужно вызвать соответствующий метод.

Первое решение, которое напрашивается само собой – использовать операторы switch или if.

Т.е. написать что-то вроде:

  1. switch (curFruit) {
  2.     case "apples" :
  3.         f.get_apples();
  4.         break;
  5.     case "oranges" :
  6.         f.get_oranges();
  7.         break;
  8.     case "pears" :
  9.         f.get_pears();
  10.         break;
  11.     default :
  12.         alert("unknown");
  13. }

Безусловно, этот код работать будет, но есть более элегантное решение:

  1. if (typeof f["get_" + curFruit] == "function") {
  2.     f["get_" + curFruit]();
  3. }
  4. else {
  5.     alert("unknown");
  6. }

Разберем его подробнее. На JavaScript к любому методу класса можно обратиться как к элементу массива. Т.е. f["get_apples"]() работает точно также как и f.get_apples().

Смысл в том, что в названии элемента массива – это обычная строка, и для ее формирования можно использовать любые переменные (в данном случае к приставке "get_" мы добавляем curFruit).

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

Очень важно. При использовании typeof можно легко ошибиться. Посмотрите на следующие две строки.

  1. typeof f["get_" + curFruit] //возвращает "function"
  2. typeof f["get_" + curFruit]() //возвращает "number"

или

  1. typeof f.get_apple //возвращает "function"
  2. typeof f.get_apple() //возвращает "number"

В первой строке оператору typeof передан метод класса, во второй – значение, которое этот метод возвращает (т.е. число 10). Разница только в круглых скобках в конце выражения.

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

Все вопросы и замечания – пишите в комментариях.

До встречи!

Понравилась статья? Подписывайтесь на продолжение rss link !

Или на мой твиттер twitter link

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в JavaScript, Web разработка Комментарии (14) »

]]>

Комментарии (14)

Вы можете отслеживать обсуждение записи с помощью RSS 2.0 rss link

Вы также можете оставить комментарий, или трекбек с Вашего сайта.

]]>
  1. Хороший подход и правильный! Как всегда отличная заметка :)

  2. Чистяков Денис

    Подход интересный и полезный, но лично мне больше импонирует другой способ создания «классов» в JavaScript'ах — не через использование прототипов, а через прямое создание методов:

    // Конструктор.
    function NewClass() {
    this.property = 123;
    // Создаем методы класса прямо в конструкторе.
    this.method1 = function(x) {
    alert("Вызван method1("+x+")");
    }
    // То же самое.
    this.method2 = function(x) {
    alert("Вызван method2("+x+")");
    this.method1();
    }
    }

    // Создаем объект и проверяем работу.
    var obj = new NewClass();
    obj.method1(10);

    подробнее: Большие хитрости JavaScript

    Это ничего принципиально не меняет в идее предложенной вами, но реализовывать удобнее )

    • Да, способ удобный. Почему-то не встречал его раньше. Вообще мне никогда не нравилось, что на JavaScript код класса можно разбросать по всему скрипту.

      Кстати, отличная статья!

  3. Чистяков Денис

    Ой, пардон ссылка вставилась не так как хотел, подправь, если не сложно.

    • Исправил, надеюсь правильно :-)

      • Чистяков Денис

        Да, спасибо.
        Там в принципе три статьи, как минимум повещены JavaScript, все очень стоящие и все актуальны и сейчас хотя написаны достаточно давно.
        Котерова, вообще интересно читать и очень познавательно, для PHP, Perl и JS разработчиков.

  4. типичные методы объекто-ориентированного программирования + особенности, характерные именно для javascript. Cпасибо за статью, буду применять на практике.

  5. Что-то я тоже про фабрику не понял не много!

  6. действительно подробней про фабрику если можно

  7. Я новичок, и мне тяжело понять про фабрику… я слыхала на плюсах есть такое. оказывается и здесь тоже..Только все равно тяжело понять. Вижу я здесь не одна такая)

]]>

Оставить комментарий

* - обязательные для заполнения поля

]]>