Урок 15. Пользовательские функции в JavaScript
Теория
Решать задачу кучей кода неудобно. Удобнее всего выносить кусочки кода в отдельные функции. В этом случае получается набор простых функций, каждая из которых выполняет 1 простое действие. Такие функции легко делать, тестировать, использовать для других задач и переносить между проектами.
Задача
Дан массив с числами. Записать в новый массив только те элементы, сумма цифр в которых от 1 до 8.
Разрабатывается вспомогательная функция g, которая параметром будет принимать число, а возвращать массив цифр. Вот эта функция:
function g(n){s=String(n);return s.split('')}
Обратите внимание на String(n). Переданное число необходимо преобразовать в строку с помощью String, иначе к нему нельзя будет применить метод split.
Тестируем нашу функцию на каком-нибудь числе:
function g(n){s=String(n);return s.split('')}console.log(g(123))//Выведет ['1','2','3']
Обратите внимание на то, что функция вернула массив строк ['1','2','3'], а не массив чисел [1,2,3]. Это результат работы split. Учтем в дальнейшем.
Следующая функция - это функция h, параметром принимающая массив и возвращающая сумму элементов этого массива. Пусть эта функция работает и с массивом ['1','2','3'], и с массивом [1,2,3]. Это достигается с помощью функции Number, в которую оборачиваются элементы массива:
function h(a){s=0;for(i=0;i<a.length;i++){s+=Number(a[i])}return s}
Тестируем комбинацию 2 функций, найдем сумму цифр заданного числа:
function g(n){s=String(n);return s.split('')};function h(a){s=0;for(i=0;i<a.length;i++){s+=Number(a[i])}return s};var s=h(g(123));document.write(s)//Выведет 6
Следующая функция - это функция e, которая параметром принимает число и возвращает true, если сумма цифр этого числа от 1 до 8, и false, если это не так. Вот эта функция:
function e(n){s=h(g(n));/*Используем вспомогательные функции*/if(s>=1&&s<=9){return true}else{return false}}
Можно переписать и короче:
function e(n){s=h(g(n));return s>=1&&s<=8}
Теперь решим исходную задачу. Дан массив с числами, записать в новый массив только те элементы, сумма цифр в которых от 1 до 8. Для этого возьмем массив с числами, переберем его циклом и в цикле с помощью функции e проверим, подходит ли этот элемент массива. Если подходит, забираем его себе:
function e(n){s=h(g(n));return s>=1&&s<=8};a=[18,19,28,38,14,288];r=[];for(i=0;i<9;i++){if(e(a[i])){/*если подходит, берем*/r.push(a[i])}}console.log(r)
Окончательное решение будет выглядеть так:
function e(n){s=h(g(n));return s>=1&&s<=8};a=[18,19,28,38,14,288];r=[];for(i=0;i<9;i++){if(e(a[i])){r.push(a[i])}}console.log(r);function e(n){var s=h(g(n));return s>=1&&s<=8}function g(n){return String(n).split('')}function h(a){var s=0;for(i=0;i<a.length;i++){s+=Number(a[i])}return s}
Задача
Дан массив с числами, найти сумму всех цифр из этих чисел.
Для решения этой задачей удобно воспользоваться функциями h и g, которые разработаны при решении предыдущей задачи:
a=[18,19,28,38,14,288];s=0;for(i=0;i<9;i++){s+=h(g(n))}document.write(s)
Советы по работе с функциями
Давайте функциям осмысленные имена.
Старайтесь давать функциям осмысленные имена. Имя должно отражать то, что делает функция. Предположим, у нас есть функция, которая осуществляет валидацию (проверку правильности заполнения) формы.
Как лучше всего ее назвать? Как-нибудь так: validateForm. И напротив, имя validate или form не будет полностью отражать то, что делает эта функция.
В идеале вы должны посмотреть на имя функции и сразу определить то, что она делает, не заглядывая в ее код.
Не делайте их очень большими.
Функции не должны быть очень большими. Нормальный размер - строк 10. Максимальный - 30 строк.
Если в функции получается больше 30, задумайтесь о том, чтобы разбить ее на несколько функций.
1 функция - 1 задача
Функции не должны быть многозадачными. Правило такое: 1 функция должна выполнять только 1 задачу.
Предположим, перед вами стоит задача: при регистрации пользователя проверить, не занято ли такое имя, и если не занято - сохранить его в базу данных. Велик соблазн сделать все одной функцией, которая будет проверять, а потом сохранять.
Однако это неправильно. Лучше будет сделать 2 функции: 1 проверяет, а 2-я сохраняет.
Используйте функции внутри функций.
Это правило вытекает из предыдущего. Внутри функций можно и нужно использовать другие функции, вспомогательные.
Делайте функции универсальными.
Старайтесь делать функции как можно более универсальными. Тот проект, который делается сейчас - не последний и написанные функции наверняка будут использованы в будущем. Поэтому при создании новой функции выделите пару минут и хорошо подумайте над ее именем, параметрами и их порядком (с точки зрения удобства).
Практика
Примеры решения задач
Задача
Дан массив с числами. Создать из него новый массив, где останутся лежать только положительные числа. Создать для этого вспомогательную функцию isPositive(), которая параметром будет принимать число и возвращать true, если число положительное, и false, если отрицательное.
Решение:
a=[1,2,3,-1,-2,-3];function isPositive(n){if(n>=0){return true}else{return false}};a2=[];for(i=0;i<=a.length;i++){if(isPositive(a[i])){a2.push(a[i])}}console.log(a2)
Задачи для решения
Сделать функцию isNumberInRange, которая параметром принимает число и проверяет, что оно >0 и меньше 8. Если это так, функция возвращает true, если не так, - false.
Дан массив с числами. Запишите в новый массив только те числа, которые >0 и меньше 8. Для этого используйте вспомогательную функцию isNumberInRange из предыдущей задачи.
Сделать функцию getDigitsSum (digit - это цифра), которая параметром принимает целое число и возвращает сумму его цифр.
Найдите все года от 1 до 2028, сумма цифр которых равна 18. Для этого используйте вспомогательную функцию getDigitsSum из предыдущей задачи.
Сделать функцию isEven() (even - это четный), которая параметром принимает целое число и проверяет: четное оно или нет. Если четное, функция возвращает true, если нечетное, - false.
Дан массив с целыми числами. Создать из него новый массив, где останутся лежать только четные из этих чисел. Для этого использовать вспомогательную функцию isEven из предыдущей задачи.
Сделать функцию getDivisors, которая параметром принимает число и возвращает массив его делителей (чисел, на которое делится данное число).