Понятие функции-коллбэка в JavaScript

Пусть у нас есть функция, возводящая в квадрат переданное параметром число:

function square(num) { return num * num; }

Пусть у нас также есть функция, которая первым параметром принимает массив, а вторым - функцию, и применяет эту функцию к каждому элементу массива:

function each(arr, func) { // тут какой-то код }

Давайте с помощью функций each и square возведем каждый элемент какого-нибудь массива в квадрат:

function square(num) { return num * num; } let result = each([1, 2, 3, 4, 5], square); console.log(result); // должно вывести [1, 4, 9, 16, 25]

Подобные функции, которые передаются параметрами другим функциям и выполняются где-то внутри них, называются коллбэками (англ. callback).

В нашем случае мы можем сказать, что вторым параметром функция each получает коллбэк.

Давайте внутри нашей функции each переименуем параметр с функцией, чтобы было более очевидно, что здесь будет передаваться коллбэк:

function each(arr, callback) { }

Как правило, коллбэки представляют собой анонимные функции (но это не обязательно).

Давайте переделаем наш код так, чтобы во второй параметр функции each передавалась анонимная функция:

let result = each([1, 2, 3, 4, 5], function(num) { return num * num; }); console.log(result); // должно вывести [1, 4, 9, 16, 25]

Давайте теперь реализуем функцию each:

function each(arr, callback) { let result = []; for (let elem of arr) { result.push( callback(elem) ); // вызываем функцию-коллбэк } return result; }

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

Дан массив со строками. С помощью созданной нами функции each переверните символы каждой строки в обратном порядке.

Дан массив со строками. С помощью созданной нами функции each сделайте заглавным первый символ каждой строки.

Количество параметров в коллбэке

Посмотрите на строчку callback(elem) внутри нашей функции each. Именно эта строчка определяет, что в функции-коллбэке будет один параметр и в него "автоматически" по очереди будут попадать элементы массива.

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

В таком случае мы бы могли, например, решить такую задачу: в конец каждого элемента массива добавить его порядковый номер:

let result = each(['a', 'b', 'c', 'd', 'e'], function(elem, index) { return elem + index; }); console.log(result); // должно вывести ['a0', 'b1', 'c2', 'd3', 'e4']

Давайте реализуем описанное:

function each(arr, callback) { let result = []; let i = 0; for (let elem of arr) { result.push( callback(elem, i++) ); // вторым параметром передаем счетчик } return result; }

Дан массив с числами. С помощью созданной нами функции each найдите произведение каждого элемента массива на его порядковый номер.

Функция filter

Реализуйте функцию filter, которая будет осуществлять фильтрацию массива. Пусть первым параметром функция принимает массив, а вторым - функцию-коллбэк, и возвращает массив элементов, для которых функция-коллбэк вернет true.

Пример работы такой функции (оставим в массиве только четные числа):

let result = filter([1, 2, 3, 4, 5], function(elem) { if (elem % 2 == 0) { return true; } else { return false; } }); console.log(result); // выведет [2, 4]

Пусть в первый параметр коллбэка попадает элемент массива, а во второй - его номер.

Дан массив с числами. С помощью созданной нами функции filter оставьте в этом массиве только положительные числа.

Дан массив со строками. С помощью созданной нами функции filter оставьте в этом массиве только строки, длина которых от 1 до 3 символов.

Функции every и some

Реализуйте функцию every, которая будет возвращать true, если для всех элементов массива функция-коллбэк вернула true, и будет возвращать false в противном случае.

Пример работы такой функции (проверим, что в массиве только положительные числа):

let result = every([1, 2, 3, 4, 5], function(elem) { if (elem > 0) { return true; } else { return false; } }); console.log(result); // выведет true

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

Пример работы такой функции (проверим, что в массиве есть хотя бы одно отрицательное число):

let result = every([1, 2, 3, 4, 5], function(elem) { if (elem < 0) { return true; } else { return false; } }); console.log(result); // выведет false

Функция alternate

Реализуйте функцию alternate, которая первым параметром будет принимать массив, а вторым и третьим - коллбэки.

Функция должна по очереди применять коллбэки к элементам массива. То есть: для первого элемента - первый коллбэк, для второго элемента - второй коллбэк, для третьего - опять первый коллбэк и так далее пока элементы массива не закончатся.

Пример работы такой функции ():

let result = alternate( ['a', 'b', 'c', 'd', 'e'], function(elem) { return elem + '!'; }, function(elem) { return elem + '?'; }, ); console.log(result); // выведет ['a!', 'b?', 'c!', 'd?', 'e!']