Suggest an editImprove this articleRefine the answer for “Passing a callback to another function”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A callback is passed simply as an argument when you call another function, because functions in JavaScript are values (first-class citizens), and inside the receiving function you call it by its parameter name.** You pass a reference to the function, with no parentheses: `doSomething(afterDone)`, not `doSomething(afterDone())`. ```javascript function doSomething(callback) { console.log('Doing something...'); callback(); // call the callback we were given } function afterDone() { console.log('Done!'); } doSomething(afterDone); // Doing something... / Done! ``` **Key point:** name the function as an argument at the call site, and inside the receiving function call it by its parameter name when you need it.Shown above the full answer for quick recall.Answer (EN)Image**To pass a callback, name the function as an ordinary argument when you call another function, and inside the receiving function call it by its parameter name.** This works because functions in JavaScript are values (first-class citizens): they can be assigned to variables, stored in arrays and passed as arguments. ## Theory ### TL;DR - A callback is passed as an ordinary argument: `doSomething(afterDone)`. - Pass a reference to the function, with no parentheses. Parentheses mean a call and pass its result, often `undefined`. - Inside the receiving function the callback is called by its parameter name: `callback()`. - You can pass a named function, an anonymous function, or an arrow function written inline at the call site. - The receiving function does not care what the callback does: it receives that behaviour from outside. ### Quick example ```javascript function doSomething(callback) { console.log('Doing something...'); callback(); // call the callback we were given } function afterDone() { console.log('Done!'); } doSomething(afterDone); ``` Output: ```text Doing something... Done! ``` ### Three ways to pass a callback The notation differs, the idea is the same: a function ends up in the `callback` parameter. ```javascript // 1. A named function, we pass a reference to it function afterDone() { console.log('Done!'); } doSomething(afterDone); // 2. An anonymous function right in the argument doSomething(function () { console.log('Done!'); }); // 3. An arrow function, the shortest form doSomething(() => { console.log('Done!'); }); ``` | Form | When it is convenient | | --- | --- | | Named function | The logic is reused in several places and is easy to test on its own | | Anonymous `function` | You need the callback to have its own `this` or `arguments` | | Arrow function | A short one-off handler, `this` is taken from the surrounding scope | ### Passing arguments into the callback The receiving function decides which arguments the callback is called with. The caller only describes what to do with those values. ```javascript function doSomething(callback) { const result = 42; callback(result); // pass data into the callback } doSomething(value => { console.log('Got', value); // Got 42 }); ``` If you need to fix your own arguments up front, wrap the call in an arrow function or use `bind`. ```javascript function greet(name) { console.log('Hello, ' + name); } doSomething(() => greet('Maria')); // wrapper keeps the argument doSomething(greet.bind(null, 'Oleh')); // the same via bind ``` ### Calling instead of passing: the main trap `afterDone` is a function, `afterDone()` is already its result. Parentheses in the argument run the function immediately, so the receiving function gets a value instead of behaviour. ```javascript doSomething(afterDone); // correct: pass the function itself doSomething(afterDone()); // wrong: runs now and passes undefined ``` The same principle holds for any API that takes a callback: `setTimeout(fn, 100)`, `addEventListener('click', fn)`, `array.map(fn)`. ### Guarding against a missing callback If the parameter is optional, check it before calling or give it a default value, otherwise you get `TypeError: callback is not a function`. ```javascript function doSomething(callback = () => {}) { console.log('Doing something...'); callback(); } doSomething(); // works even without an argument ``` ### Common mistakes - Passing `afterDone()` instead of `afterDone`: the function runs immediately and the parameter receives `undefined`. - Writing parentheses in `setTimeout(sayHi(), 100)` and then wondering why the timer does nothing. - Calling the callback without checking that one was actually passed, and getting a `TypeError`. - Passing an object method directly, `obj.handler`, and losing `this`. An arrow wrapper or `bind` fixes it. - Expecting a value from an asynchronous callback to be available right after the function call: it only appears once the callback actually runs.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.