DEV Community

Cover image for Understanding Call, Apply and Bind by creating them - Javascript
Shanoy Sinclair
Shanoy Sinclair

Posted on

Understanding Call, Apply and Bind by creating them - Javascript

Creating stuff with the tools that you are using is pretty fun but you know what's amazing is when you know how to create the tools that you are using. So I started to experiment with small javascript methods such as call, apply, and bind. I even created react virtual dom and Git but I will leave that for another post. So let's get into it starting with the Call method!

The JavaScript call() Method

The call method allows us to change what the this value of a function is point to eg.

function greeting(lan) {
    console.log(`My name is ${this.name} and I am learning ${lan}`);
}

let Shanoy = {
    name: "Shanoy",
};

let Lamar = {
    name: "Lamar",
};
Enter fullscreen mode Exit fullscreen mode

If we were to call the greeting function the this.name would point to the Global window object and search for a property called name. But that's not what we want. We want it to point to an object that we specify which is Lamar and Shanoy

greeting.call(Shanoy, "React"); 
//return My name is Shanoy and I am learning React


greeting.call(Lamar, "Vue"); 
//return My name is Lamar and I am learning Vue
Enter fullscreen mode Exit fullscreen mode

Did you see that? The call method is now pointing to Lamar and Shanoy Object. Now that you understand call lets implement our own which is quite simple

Object.prototype.calling = function (obj, ...args) {
    const newObj = Object.assign({}, obj, { newMethod: this });
    return newObj.newMethod(...args);
};

greeting.calling(Shanoy, "React");
//return My name is Shanoy and I am learning React

greeting.calling(Lamar, "Vue");
//return My name is Lamar and I am learning Vue
Enter fullscreen mode Exit fullscreen mode

So what we are doing above is creating a new method call calling to work on every Object that's why we place it on the global object prototype. It takes two arguments:

  1. Our Object that we want the this value to change to
  2. The rest of the arguments that were specified on the greeting function

The three dots(...) in front of the args is a spread operator that turns all arguments after the first into an array

Next, we need to create a new object combine with the object we want the this value to change to and the current this value which is the greeting function. There is no way we can save a function in an object without placing it with a key pair value that's why we place it on the newMethod key

const newObj = Object.assign({}, obj, { newMethod: this });
Enter fullscreen mode Exit fullscreen mode

Final we return the new object that we created and call the newMethod as you can see the greeting function is now point to our
object that we specify and we spread the arguments out of the array and into our greeting function

return newObj.newMethod(...args);
Enter fullscreen mode Exit fullscreen mode

The JavaScript apply() Method

Apply is similar to call the only difference is if the second argument that your passing in is an array and not a string

Object.prototype.applying = function (obj, args) {
    const newObj = Object.assign({}, obj, { newMethod: this });
    if (!Array.isArray(args)) {
        throw new Error("Second argument should be an Array");
    }
    return newObj.newMethod(...args);
};
Enter fullscreen mode Exit fullscreen mode

Do you notice that we are not spreading the args parameter that's because we are expecting an array as an argument.

greeting.applying(Shanoy, ["React"]);
//return My name is Shanoy and I am learning React
Enter fullscreen mode Exit fullscreen mode

The JavaScript bind() Method

The bind method is kind of similar to call and apply but it returns a function and we would have to invoke it for it to run eg.

let greet = greeting.bind(Shanoy);
greet("golang");
Enter fullscreen mode Exit fullscreen mode

We change the this value to Shanoy object and save the return function in the greet variable to call at a later date and that's the power of the bind method. Here's our implementation of it

Object.prototype.binding = function (obj) {
    const newObj = Object.assign({}, obj, { newMethod: this });
    return function () {
        return newObj.newMethod(...arguments);
    };
};
Enter fullscreen mode Exit fullscreen mode

Did you see what we are doing differently instead of return the newobj we return a function. When we return a function it won't run unless we invoke it

let greet = greeting.binding(Shanoy);
greet("golang");
// return My name is Shanoy and I am learning golang


let lamarGreet = greeting.binding(Lamar);
lamarGreet("Flutter");
// return My name is Lamar and I am learning Flutter
Enter fullscreen mode Exit fullscreen mode

A quick run down of what each method does

  1. Call invokes the function immediately and allows you to pass in arguments one by one
  2. Apply invokes the function immediately and allows you to pass in arguments as an array.
  3. Bind returns a new function, and you can invoke/call it anytime you want by invoking a function.

Thank you guys for reading my post it was my first post so I hope you guys learned something new I know I did. I just learn a few MarkDown syntaxes.

Top comments (0)