Js передать функцию как параметр
Перейти к содержимому

Js передать функцию как параметр

  • автор:

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]

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] 
  1. Массив чисел
  2. Анонимная функция, которая принимает на вход число и возвращает логическое значение

Упражнение не проходит проверку — что делать? ��

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

  • Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.

В моей среде код работает, а здесь нет ��

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя ��

Это нормально ��, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно ��

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.

Полезное

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

Ошибка возникает из-за некорректного определения. В этом коде вы определяете новую функцию mult. При этом в круглых скобках должны указываться формальные параметры, а не конкретные аргументы, как у вас. Конкретные аргументы (будь то обычное значение или функция) будут передаваться в будущем, во время вызова созданной вами функции. На стадии определения функции указывается формальный параметр на место которого будет подставлено конкретное значение во время вызова этой функции. При этом формальный параметр должен иметь обыкновенное имя, например, par, num или любое другое подходящее. Вы же в определении функции пытаетесь сделать вызов формального параметра sun(), что не имеет смысла и приводит к ошибке.

Если хотите иметь возможность передавать одну функцию в другую, то для начала эти функции нужно опередить, а затем уже передать при вызове, например так:

function sun() < var x = Math.floor(Math.random() * (4 - 1 + 1)) + 1; console.log(x); return x; >function mult(func) < var x = 5 + func(); console.log(x); >// при вызове на место формального параметра func будет // подставлен фактический аргумент-функция sun mult(sun);

как передать объект в функцию js

Пример функции, в которую передается объект в качестве параметра:

function changeObject(obj)  obj.name = 'Василий'; obj.age = 30; > 

Эта функция принимает объект obj в качестве параметра. Затем она изменяет его свойства name и age .

Параметр obj передается по ссылке, а не по значению. Это означает, что функция получает не копию объекта, а ссылку на него. Если функция изменяет свойства объекта, эти изменения будут видны и вне функции.

Например, если объявить объект person и передать его в функцию changeObject , свойства name и age будут изменены:

const person =  name: 'Алиса', age: 25 >; changeObject(person); console.log(person); // 

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

В таком случае нужно быть осторожным при передаче объектов в качестве параметров функций и учитывать, и если необходимо, создавать копию объекта.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *