Javascript Callbacks
Callbacks offer a way to extend the functionality of a function (or method) without changing its code. This approach is often used in modules (libraries / plugins), the code of which is not supposed to be changed.
Suppose we have written the following function, calculating the sum of a given array of values:
function foo(array) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
sum += array[i];
}
return sum;
}
Now suppose that we want to do something with each value of the array, e.g. display it using alert(). We could
make the appropriate changes in the code of foo, like this:
function foo(array) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
alert(array[i]);
sum += array[i];
}
return sum;
}
But what if we decide to use console.log instead of alert()? Obviously changing the code of foo, whenever we decide to do something else with each value, is not a good idea. It is much better to have the option to change our mind without changing the code of foo. That's exactly the use case for callbacks. We only have to slightly change foo's signature and body:
function foo(array, callback) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
callback(array[i]);
sum += array[i];
}
return sum;
}
And now we are able to change the behaviour of foo just by changing its parameters:
var array = [];
foo(array, alert);
foo(array, function (x) {
console.log(x);
});
This is a normal function call:
console.log("Hello World!");
Output
When you call a normal function, it does its job and then returns control back to the caller.
Thus, the function map is essentially returning control back to the caller every time it calls the function double. Hence, the name “callback”.
Functions may accept more than one callback:
promise.then(function onFulfilled(value) {
console.log("Fulfilled with value " + value);
}, function onRejected(reason) {
console.log("Rejected with reason " + reason);
});
Here then function then accepts two callback functions, onFulfilled and onRejected. Furthermore, only one of
these two callback functions is actually called.
What's more interesting is that the function then returns before either of the callbacks are called. Hence, a callback
function may be called even after the original function has returned.
Callbacks and `this
Often when using a callback you want access to a specific context.
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', function() {
console.log(this.msg); // <= will fail because "this" is undefined
});
}
var s = new SomeClass("hello", someElement);