Функции, подобно числам, строкам и массивам, могут передаваться параметрами в другие функции.
Рассмотрим подробнее на практическом примере.
Пусть у нас есть функция test, принимающая два параметра:
test(параметр1, параметр2);
Давайте в первый параметр функции test передадим анонимную функцию, возвращающую 1, а во второй параметр - анонимную функцию, возвращающую 2:
test(
function() {return 1;},
function() {return 2;}
);
Код, приведенный выше, пока не рабочий, так как мы не создали саму функцию. Сделаем это:
function test(func1, func2) {
}
При определении функции мы указали два параметра - func1 и func2. Эти параметры ничего не знают про то, что в них будет передаваться. Можем, например, передать числа:
test(1, 2); // вызываем функцию
function test(func1, func2) {
alert(func1); // выведет 1
alert(func2); // выведет 2
}
А можем передать функции:
test(
function() {return 1;}, // первый параметр
function() {return 2;} // второй параметр
);
function test(func1, func2) {
alert(func1); // выведет 'function() {return 1;}'
alert(func2); // выведет 'function() {return 2;}'
}
Как вы видите, теперь алерт выводит исходный код функций. Давайте сделаем так, чтобы он выводил их результаты. Для этого напишем функциям круглые скобки:
test(
function() {return 1;},
function() {return 2;}
);
function test(func1, func2) {
alert( func1() ); // выведет 1
alert( func2() ); // выведет 2
}
Как вы видите, теперь алерт выводит исходный код функций. Давайте сделаем так, чтобы он выводил их результат. Для этого напишем функциям круглые скобки:
test(
function() {return 1;},
function() {return 2;}
);
function test(func1, func2) {
alert( func1() ); // выведет 1
alert( func2() ); // выведет 2
}
Давайте выведем на экран сумму результатов первой и второй функции:
test(
function() {return 1;},
function() {return 2;}
);
function test(func1, func2) {
alert( func1() + func2() ); // выведет 3
}
Сделайте функцию test, параметрами принимающую 3 функции. Передайте в нее первым параметром функцию, возвращающую 1, вторым - функцию, возвращающую 2, третьим - функцию, возвращающую 3. Выведите на экран сумму результатов функций.
Именованные функции
Функции, которые передаются параметрами, не обязательно должны быть анонимными.
Давайте сделаем их как Function Declaration. Первую функцию назовем get1, а вторую - get2:
function get1() {
return 1;
}
function get2() {
return 2;
}
Передадим в параметры функции test имена функций get1 и get2 (то есть их исходный код, а не результат):
function get1() {
return 1;
}
function get2() {
return 2;
}
test(get1, get2); // выведет 3
function test(func1, func2) {
alert( func1() + func2() );
}
Переделаем на Function Expression:
let get1 = function() {
return 1;
}
let get2 = function() {
return 2;
}
test(get1, get2); // выведет 3
function test(func1, func2) {
alert( func1() + func2() );
}
Сделайте функцию test, параметрами принимающую 3 функции и возвращающую сумму результатов переданных функций.
Сделайте 3 функции, объявив их как Function Declaration и дав им имена func1, func2 и func3. Пусть первая функция возвращает 1, вторая - 2, а третья - 3. Передайте эти функции параметром в функцию test из предыдущей задачи.
Модифицируйте предыдущую задачу так, чтобы функции были объявлены как Function Expression с теми же именами.
Параметры передаваемых функций
Пусть у нас есть функция test, которая параметром принимает другую функцию и алертом выводит результат работы этой переданной функции:
function test(func) {
alert( func() );
}
Пусть переданная функция func параметром принимает число и что-то с ним делает. Передадим ей, например, число 3:
function test(func) {
alert( func(3) );
}
Давайте теперь вызовем функцию test, передав в нее параметром анонимную функцию. Эта анонимная функции параметром будет принимать число и возвращать квадрат этого числа.
В результате всего этого наша конструкция выведет квадрат числа 3, то есть 9:
// Выведет 9:
test(
function(num) {
return num * num;
}
);
function test(func) {
alert(func(3));
}
Оформим код более изящно:
// Выведет 9:
test(function(num) {
return num * num;
});
function test(func) {
alert(func(3));
}
Скопируйте код моей функции test. Вызовите эту функцию, передав ей параметром анонимную функцию, которая параметром будет принимать число и возвращать его куб.
Переделайте ваш код так, чтобы передаваемая функция была не анонимной, а была определена как Function Declaration с именем func.
Переделайте передаваемую функцию на Function Expression с тем же именем func.
Пусть передаваемая функция теперь принимает два параметра и возвращает их сумму. При вызове передаваемая функции внутри test передайте в передаваемую функцию число 2 и число 3. Выведите алертом результат.
Передадим и число параметром
Давайте теперь число, с которым что-то делает передаваемая функция, не будем жестко хранить внутри test, а передадим первым параметром:
function test(num, func) { // первым параметром приходит число
alert(func(num));
}
Воспользуемся нашей функцией:
function test(num, func) {
alert(func(num));
}
// Выведет 4:
test(2, function(num) {
return num * num;
});
В удобство нашей конструкции: у нас есть одна функция test, параметром принимающая число. Но то, что будет происходить с числом не зашито жестко в функции test.
Мы можем, к примеру, вторым параметром функции test передать функцию, возводящую в квадрат, а можем, к примеру, возводящую в куб:
function test(num, func) {
alert(func(num));
}
// Найдем квадрат числа:
test(2, function(num) {
return num * num; // возвращает квадрат
});
// Найдем куб числа:
test(2, function(num) {
return num * num * num; // возвращает куб
});
Пусть функция test первым параметром принимает число, а вторым и третьим параметрами - функции, также параметром принимающие числа.
Пусть функция test возвращает сумму результатов переданных функций:
function test(num, func1, func2) {
return func1(num) + func2(num);
}
Вызовите функцию test, первым параметром передав число 3, вторым параметром функцию, возводящую число в квадрат, а третьим - функцию, возводящую число в куб. Выведите результат работы на экран.
Применение
Давайте сделаем функцию, которая параметром будет принимать массив, а вторым параметром - функцию. Переданная функция должна будет применится к каждому элементу массива:
function test(arr, func) {
// вернем измененный массив
}
Реализуем:
function test(arr, func) {
// Запускаем цикл:
for (let i = 0; i < arr.length; i++) {
arr[i] = func(arr[i]); // применяем функцию к каждому элементу
}
return arr; // возвращаем измененный массив
}
Применим нашу функцию к какому-нибудь массиву:
function test(arr, func) {
for (let i = 0; i < arr.length; i++) {
arr[i] = func(arr[i]);
}
return arr;
}
// Преобразуем массив чисел в массив их квадратов:
let result = test(
[1, 2, 3],
function(num) {return num * num;}
);
console.log(result); // выведет [1, 4, 9]
Оформим вызов нашей функции изящнее (так более принято):
function test(arr, func) {
for (let i = 0; i < arr.length; i++) {
arr[i] = func(arr[i]);
}
return arr;
}
// Оформим код изящнее:
let result = test([1, 2, 3], function(num) {
return num * num;
});
console.log(result); // выведет [1, 4, 9]
Не подсматривая в мой код реализуйте такую же функцию test самостоятельно.
Вызовите созданную вами функцию test, передав ей параметром массив с числами. Сделайте так, чтобы функция вернула массив с кубами этих чисел.