Передача функций параметрами в JavaScript

Функции, подобно числам, строкам и массивам, могут передаваться параметрами в другие функции.

Рассмотрим подробнее на практическом примере. Пусть у нас есть функция 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() + 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, передав ей параметром массив с числами. Сделайте так, чтобы функция вернула массив с кубами этих чисел.