JavaScript: передать функцию JavaScript в качестве параметра
Напишите программу JavaScript для передачи «функции JavaScript» в качестве параметра.
function addFunc(id, refreshCallback) < //ваш код >addFunc(1, refreshFunc); // Hello Function
Выполнить код » Скрыть результаты

Комментарии
пожелания к комментариям…
- Приветствуются комментарии, соответствующие теме урока: вопросы, ответы, предложения.
- Одну строчку кода оборачивайте в тег
, несколько строчек кода — в теги. ваш код..
- Допускаются ссылки на онлайн-песочницы (codepen, plnkr, JSBin и др.).
TypeScript: Функции как параметры
В TypeScript используется несколько способов типизировать функции, которые передаются как параметры. В этом уроке мы научимся работать с ними.
Как типизировать функции, которые передаются как параметры
Самый простой способ типизировать функции как параметры — использовать тип Function . Он описывает функцию JavaScript со всеми ее особенностями, включая свойства bind , call и apply .
Опишем входной параметр callback функции process :
function process(callback: Function) < const value = callback(); // . >
Function отключает проверку типов для вызываемой функции. В итоге количество и тип входных аргументов не проверяются, а результатом работы такой функции будет any . Это может привести к логическим ошибкам и неожиданному поведению:
process(Math.round); // ?
Данный пример сработает, хотя поведение вряд ли будет ожидаемым, так как Math.round вызовется без аргументов и вернет NaN . Поэтому мы рекомендуем избегать использования Function .
Другой способ описывать функции — использовать стрелочную функцию с указанием входных и выходных типов:
function process(callback: () => string) < // value имеет тип string const value = callback(); // . >process(Math.round); // Argument of type '(x: number) => number' is not // assignable to parameter of type '() => string'.
Определение стрелочной функции похоже на настоящую, но тут важно не перепутать. Здесь мы видим именно описание типа, а не определение функции.
Рассмотрим еще несколько примеров для закрепления:
function process(callback: () => number) function process(callback: () => string[]) function process(callback: () => < firstName: string; >)
Параметры синтаксически указываются так же, как и для стрелочных функций:
function process(callback: (n: number) => string) < const value = callback(10); // . >
Здесь мы определили тип callback функцией с параметром n с типом number и возвращаемое значение string .
Если определение функции встречается часто, то для него можно создать псевдоним:
type myFunction = (n: number) => string; function process(callback: myFunction) < const value = callback(10); // . >
Такая запись упрощает чтение кода и позволяет избежать дублирования.
Задание
Реализуйте функцию filter() , которая принимает на вход массив чисел и предикат. Последний будет использоваться для проверки каждого числа на соответствие требованиям:
const numbers = [1, -5, 2, 3, 4, 133]; filter(numbers, (n) => n > 3); // [4, 133] filter(numbers, (n) => n % 2 == 0); // [2, 4]
- Массив чисел
- Анонимная функция, которая принимает на вход число и возвращает логическое значение
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Полезное
Как передать функцию в функцию js
Функция в функцию передаётся как обычный параметр, так же, как это работает с любыми другими значениями. Например:
const sayHello = () => console.log('Hello!'); >; const execFunc = (func) => func(); >; execFunc(sayHello); // => Hello!
Частая ошибка, когда новички передают не саму функцию, а вызов функции. Будьте внимательны, при таком подходе, сначала вычислиться то, что мы передаём, затем это значение попадёт в функцию:
const sayHello = () => console.log('Hello!'); >; const execFunc = (func) => func(); >; execFunc(sayHello()); // => TypeError: func is not a function
Ошибка возникает, потому что в функцию execFunc() передаётся не функция, а вызов функции sayHello() .
Js передать функцию как параметр
Строки, числа, логические значения передаются в функцию по значению . Иными словами при передаче значения в функцию, эта функция получает копию данного значения. Рассмотрим, что это значит в практическом плане:
function change(x) < x = 2 * x; console.log("x in change:", x); >let n = 10; console.log("n before change:", n); // n before change: 10 change(n); // x in change: 20 console.log("n after change:", n); // n after change: 10
Функция change получает некоторое число и увеличивает его в два раза. При вызове функции change ей передается число n. Однако после вызова функции мы видим, что число n не изменилось, хотя в самой функции произошло увеличение значения параметра. Потому что при вызове функция change получает копию значения переменной n. И любые изменения с этой копией никак не затрагивают саму переменную n. В итоге мы получим следующий вывод в консоли браузера
n before change: 10 x in change: 20 n after change: 10
Передача по ссылке
Объекты и массивы представляют ссылочные типы. То есть переменная или константы, которая представляет объект или массив, по сути хранит ссылку или иными словами указатель, которые указывают на адрес в памяти, где хранится объект. Например:
let bob =< name: "Bob" >;
Переменная bob формально хранит объект, в котором определено одно поле name. Фактически же переменная bob хранит ссылку на объект, который расположен где-то в памяти.
И ссылочные типы - объекты и массивы передаются в функцию по ссылке . То есть функция получает копию ссылки на объект, а не копию самого объекта.
function change(user) < user.name = "Tom"; >let bob =< name: "Bob" >; console.log("before change:", bob.name); // Bob change(bob); console.log("after change:", bob.name); // Tom
В данном случае функция change получает некоторый объект и меняет его свойство name. При вызове этой функции в нее передается значение переменной bob:
change(bob);
Но поскольку переменная bob представляет объект и хранит ссылку на некоторый объект в памяти, то функция change получае копию этой ссылки, которая указывает на тот же объект в памяти, что и переменная bob.
В итоге мы увидим, что после вызова функции изменился оригинальный объект bob, который передавался в функцию.
before change: Bob after change: Tom
Однако если мы попробуем переустановить объект или массив полностью, оригинальное значение не изменится.
function change(user)< // полная переустановка объекта user= < name:"Tom" >; > let bob =< name: "Bob" >; console.log("before change:", bob.name); // Bob change(bob); console.log("after change:", bob.name); // Bob
Почему здесь данные не изменяются? Потому что, как писалось выше, функция получает копию ссылки . То есть при передачи в функцию параметру user значения переменной bob:
change(bob);
Переменная bob и параметр user представляют две разные ссылки, но которые указывают на один и тот же объект.
При присвоении параметру в функции другого объекта:
user= < name:"Tom" >;
ссылка user начиначет указывать на другой объект в памяти. То есть после этого bob и user - две разные ссылки, которые указывают на два разных объекта в памяти.
То же самое касается массивов:
function change(array) < array[0] = 8; >function changeFull(array) < array = [9, 8, 7]; >let numbers = [1, 2, 3]; console.log("before change:", numbers); // [1, 2, 3] change(numbers); console.log("after change:", numbers); // [8, 2, 3] changeFull(numbers); console.log("after changeFull:", numbers); // [8, 2, 3]
