Skip to content
Home » Posts » “bind” function in JavaScript

“bind” function in JavaScript

    bind function returns a new function with its context (this) set to a given value. It prepends the arguments given to it to the arguments which are passed when calling the new function. It is defined on the prototype of Function class.

    Function.prototype.bind

    Syntax

    bind(thisArg, arg1, …, argN)
    • thisArg – Value to be used as context (this) when calling the new function. As per MDN, if it is not provided then the execution scope will be used as thisArg for the new function.
    • arg1, …, argN – Optional – Arguments which will be prepended before the arguments passed in the new function.

    Examples

        const starWars = {
            master: 'Obi-Wan Kenobi',
            disciple: 'Anakin Skywalker'
        };
    
        function printDetails() {
            console.log(`${this.master} trained ${this.disciple}`);
        }
    
        printDetails();
    
        const boundedPrintDetails = printDetails.bind(starWars);
        boundedPrintDetails();
    undefined trained undefined
    Obi-Wan Kenobi trained Anakin Skywalker
        const permanentTeam = {
            dev1: 'Mike',
            dev2: 'Ae-Cha',
            engineeringManager: 'William'
        };
    
        function printTeamDetails(...contractDevs) {
            console.log(`
            Permanent Members:
            Dev 1 - ${this.dev1}
            Dev 2 - ${this.dev2}
            Engineering Manager - ${this.engineeringManager}
            Contract Developers - ${contractDevs.join(', ')}
            `);
        }
    
        printTeamDetails('Alice', 'Adele');
        printTeamDetails.bind(permanentTeam, 'Angela', 'Edith')('Alice', 'Adele');
            Permanent Members:
            Dev 1 - undefined
            Dev 2 - undefined
            Engineering Manager - undefined
            Contract Developers - Alice, Adele
    
    
            Permanent Members:
            Dev 1 - Mike
            Dev 2 - Ae-Cha
            Engineering Manager - William
            Contract Developers - Angela, Edith, Alice, Adele

    Can we write our own “bind” function?

    Let’s see if we can have our own implementation of “bind” function.

        Function.prototype.myBind = function (thisArg, ...bindArgs) {
            if (thisArg === null || thisArg === undefined) {
                throw new Error('this not provided');
            }
    
            const originalFunction = this;
            const newFunction = function (...funcArgs) {
                const newContext = Object.create(thisArg);
                const allArgs = bindArgs.concat(funcArgs);
    
                newContext[originalFunction.name] = originalFunction;
                return newContext[originalFunction.name](...allArgs);
            }
    
            return newFunction;
        }

    Let’s use the above example only to test out our implementation.

        const permanentTeam = {
            dev1: 'Mike',
            dev2: 'Ae-Cha',
            engineeringManager: 'William'
        };
    
        function printTeamDetails(...contractDevs) {
            console.log(`
            Permanent Members:
            Dev 1 - ${this.dev1}
            Dev 2 - ${this.dev2}
            Engineering Manager - ${this.engineeringManager}
            Contract Developers - ${contractDevs.join(', ')}
            `);
        }
    
        printTeamDetails('Alice', 'Adele');
        printTeamDetails.myBind(permanentTeam, 'Angela', 'Edith')('Alice', 'Adele');
    
    
            Permanent Members:
            Dev 1 - undefined
            Dev 2 - undefined
            Engineering Manager - undefined
            Contract Developers - Alice, Adele
    
    
            Permanent Members:
            Dev 1 - Mike
            Dev 2 - Ae-Cha
            Engineering Manager - William
            Contract Developers - Angela, Edith, Alice, Adele
    

    Though we were able to create our own “bind” function, it should be noted that the above code is nowhere near to the original “bind” function and should be used only for learning purposes.

    Explanation

    1. Define a new function on prototype of Function class. We are doing this because we want our function to be available on all functions rather taking them as argument.
    2. Check if thisArg is provided, throw an error if not. Original bind function, however, do not throw an error. We have added this for our simplicity only.
    3. Store the reference to the calling function (this) in a new variable.
    4. Create a new function which
      1. Creates a new object with its prototype set to thisArg. Why? Because we don’t want to make the original context (thisArg) dirty.
      2. Concatenates the arguments given in myBind and the new function.
      3. Adds the original function as a property to the new object.
      4. Executes the original function on the new object and return the result.
    5. Return the new function.

    References

    1. Mozilla Developer Network (MDN)

    Leave a Reply

    Your email address will not be published.