Эта заметка о приеме, который позволяет сократить количество JavaScript кода и сделать его легко читаемым.
Представьте такую ситуацию. В зависимости от значения полученного параметра вы должны вызвать один из методов класса. Набор возможных значений заранее определен и для каждого из них существует метод.
Чтобы не быть голословным, приведу пример такого класса.
function Fruits() { this.apples = 10; this.oranges = 20; this.pears = 30; } Fruits.prototype.get_apples = function() { return this.apples; } Fruits.prototype.get_oranges = function() { return this.oranges; } Fruits.prototype.get_pears = function() { return this.pears; }
Создать экземпляр этого класса можно так:
var f = new Fruits;
Предположим, что пользователь видит перед собой форму с выпадающим списком, в котором может выбрать название фрукта.
Нам нужно написать функцию-обработчик, которая будет возвращать количество фруктов.
Для этого мы определяем, какой пункт списка (фрукт) выбрал пользователь, и сохраняем его название в переменной curFruit
. Теперь нужно вызвать соответствующий метод.
Первое решение, которое напрашивается само собой – использовать операторы switch
или if
.
Т.е. написать что-то вроде:
switch (curFruit) { case "apples" : f.get_apples(); break; case "oranges" : f.get_oranges(); break; case "pears" : f.get_pears(); break; default : alert("unknown"); }
Безусловно, этот код работать будет, но есть более элегантное решение:
if (typeof f["get_" + curFruit] == "function") { f["get_" + curFruit](); } else { alert("unknown"); }
Разберем его подробнее. На JavaScript к любому методу класса можно обратиться как к элементу массива. Т.е. f["get_apples"]()
работает точно также как и f.get_apples()
.
Смысл в том, что в названии элемента массива – это обычная строка, и для ее формирования можно использовать любые переменные (в данном случае к приставке "get_"
мы добавляем curFruit
).
Теперь взгляните на использование оператора typeof
. Он просто возвращает тип объекта. В данном примере мы используем его для того, чтобы определить существует выбранный метод или нет.
Очень важно. При использовании typeof
можно легко ошибиться. Посмотрите на следующие две строки.
typeof f["get_" + curFruit] //возвращает "function" typeof f["get_" + curFruit]() //возвращает "number"
или
typeof f.get_apple //возвращает "function" typeof f.get_apple() //возвращает "number"
В первой строке оператору typeof
передан метод класса, во второй – значение, которое этот метод возвращает (т.е. число 10). Разница только в круглых скобках в конце выражения.
Главное преимущество этого приема в том, что вам не нужно изменять функцию-обработчик при добавлении новых методов класса.
Все вопросы и замечания – пишите в комментариях.
До встречи!