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

Владимир | | JavaScript, Web разработка.

Эта заметка о приеме, который позволяет сократить количество 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). Разница только в круглых скобках в конце выражения.

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

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

До встречи!