Skip to main content

Command Palette

Search for a command to run...

JavaScript - Callback Function

Updated
JavaScript - Callback Function

Callback Function

A function that is passed as a parameter into another function

In other words, a callback function is a function that delegates its control to another code (function or method) by passing itself as an argument. The code that receives the callback function executes it at an appropriate point in its internal logic, and the control of when to execute the callback function is delegated to the receiving code.

Callback Can Get a Control of...

When to Call

setInterval(): repeatedly perform the logic received from the callback as a parameter

var count = 0;
var cbFunc = function () {
    console.log(count);
    if (++count > 4) clearInterval(timer);
};

cbFunc(); // when calling cbFunc() like this, we can't control the time when the function executes
var timer = setInterval(cbFunc, 3000); // by putting it as a callback function, we can control when to call the function

Parameters

map(): create a new array with the results of calling a provided function on every element in the calling array

var newArr = [10, 20, 30].map(function (currVal, index) {
    console.log(currVal, index);
    return currVal * 2;
});

console.log(newArr); // [20, 40, 60]

this

A callback function is a function where this will be the global object

But, if the callback function explicitly sets the value of this, then it will be the value of this.

// creating our own map() to understand how methods related to the callback function work
Array.prototype.mapByMe = function (callback, thisArg) {
    var mappedArr = [];

    for (var i = 0; i < this.length; i++) {
        var mappedValue = callback.call(thisArg || global, this[i]); // first argument: if thisArg exists, use thisArg, otherwise use global & second argument: current value
        mappedArr[i] = mappedValue;
    }
    return mappedArr;
};

const newArr = [1, 2, 3].mapByMe((item) => {
    return item * 2;
});

console.log(newArr);

Therefore, to take over the control for this while using map() or other methods, we can explicitly put this as a second argument.

A Callback function is a function

If we pass the object's method through the callback function, the method is not the method but the function.

var obj = {
    vals: [1, 2, 3],
    logValues: function (v, i) {
        if(this === global) {
            console.log('this is global');
        } else {
            console.log(this, v, i);
        }
    },
};

// call logValues() as a method
obj.logValues(1, 2); // { vals: [ 1, 2, 3 ], logValues: [Function: logValues] } 1 2

// callback => this is not calling a method
// we just pass the function (not related to the obj object)
[4, 5, 6].forEach(obj.logValues); // this is global x3

ThisBinding

To bind different values to this inside the callback function

  1. Traditional way

var obj1 = {
    name: 'obj1',
    func: function() {
        var self = this; // here
        return function () {
            console.log(self.name);
        };
    }
};

// It is just passing the function, so not related to obj1
// i.e. It is calling the function, not as a method
var callback = obj1.func();
setTimeout(callback, 1000);
  1. Refactoring the traditional way

var obj1 = {
    name: 'obj1',
    func: function() {
        var self = this; // here
        return function () {
            console.log(self.name);
        };
    }
};

var obj2 = {
    name: 'obj2',
    func: obj1.func
};

var callback2 = obj2.func();
setTimeout(callback2, 1000); // obj2

var obj3 = { name: 'obj3' };
var callback3 = obj1.func.call(obj3);
setTimeout(callback3, 1500); // obj3
  1. By using bind() - preferred

var objBind1 = {
    name: 'objBind1',
    func: function () {
        console.log(this.name);
    }
};

setTimeout(objBind1.func.bind(objBind1), 2000); // obj1

var objBind2 = { name: 'objBind2' };

setTimeout(objBind1.func.bind(objBind2), 2500); // obj2

Callback Hell

  • too many indentations w/ nested functions

  • bad for readability and maintainability

    Callback Hell and How to Rescue it ? - DEV Community