Javascript call() & apply() vs bind()?
Asked Answered
P

24

1006

I already know that apply and call are similar functions which set this (context of a function).

The difference is with the way we send the arguments (manual vs array)

Question:

But when should I use the bind() method ?

var obj = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));

jsbin

Photocurrent answered 16/3, 2013 at 21:40 Comment(8)
It's not your fault if there are users that look at the OP's reputation points before posting an answer or upvoting :)Herniorrhaphy
call and apply call a function while bind creates a function. Though with call() you pass arguments individually and apply() as an argument array. For more details check out the linked documentation which should be able to completely answer your question.Flammable
kind of weird there is not an existing question about this : Regarding that. That is probably because bind() was added after the other two already existed in JavaScript 1.8.5 - ECMA-262, 5th edition. While call() and apply() have been around since JavaScript 1.3 - ECMA-262 3rd Edition. SO has questions on them like: what-is-the-difference-between-call-and-apply. I'm only guessing though as I was wondering that myself.Flammable
do you need these methods(call,apply,bind) here ?? without this you can also call the method and this will point to object onlyCountdown
@Flammable If I am right, bind is like map. map creates a new array and bind creates a new function. Am I?Yount
Is this the same "call" as in "Array.prototype.slice.call", which is also hard to understand?Cove
Is obj.call(arg) the same as func(arg) except that "this" is set to obj in the former, to implement class instance methods?Cove
Does this answer your question? What is the use of the JavaScript 'bind' method?Bimbo
P
273

I created this comparison between function objects, function calls, call/apply and bind a while ago:

enter image description here

.bind allows you to set the this value now while allowing you to execute the function in the future, because it returns a new function object.

Pancho answered 6/2, 2019 at 20:42 Comment(0)
B
911

Use .bind() when you want that function to later be called with a certain context, useful in events. Use .call() or .apply() when you want to invoke the function immediately, and modify the context.

Call/apply call the function immediately, whereas bind returns a function that, when later executed, will have the correct context set for calling the original function. This way you can maintain context in async callbacks and events.

I do this a lot:

function MyObject(element) {
    this.elm = element;

    element.addEventListener('click', this.onClick.bind(this), false);
};

MyObject.prototype.onClick = function(e) {
     var t=this;  //do something with [t]...
    //without bind the context of this function wouldn't be a MyObject
    //instance as you would normally expect.
};

I use it extensively in Node.js for async callbacks that I want to pass a member method for, but still want the context to be the instance that started the async action.

A simple, naive implementation of bind would be like:

Function.prototype.bind = function(ctx) {
    var fn = this;
    return function() {
        fn.apply(ctx, arguments);
    };
};

There is more to it (like passing other args), but you can read more about it and see the real implementation on the MDN.

Bushranger answered 16/3, 2013 at 21:44 Comment(16)
@RoyiNamir that is correct, you can use the returned "bound" function later, and the context will be maintained.Bushranger
That is exactly what bind returns.Bushranger
You can also use bind for partials, passing in arguments before the function is called.Chelonian
As an alternative for events I believe you can provide the handleEvent method on your prototype and then pass this itself as the event handler.Anishaaniso
So why wouldn't one use function (){this.onClick.apply(this)}) rather than call in order to be compatible with earlier browser versions? Any downside to such an approach?Fawne
@Fawne That doesn't work, this in that function refers to the context that the function you just listed is called in. If you pass that to say a DOM event, this will be the target of the event.Bushranger
I see that in my haste, I didn't post the snippet correctly. It should have been something like this return this.element.addEventListener(event, function () {callback.call(caller); Here's a JSFiddle. Since call works with older browsers, it seems using it is a better choice than using bind unless bind is bringing something else to the party? (Naturally element and caller have been correctly initialized as the fiddle shows.)Fawne
You are just reimplementing bind, there isn't really a difference. Either way you are just wrapping it in a closure that has access to a scope variable that holds the context. Your code is basically the polyfill I posted.Bushranger
@Bushranger If the function is function test(a,b,c){..} which one among call & apply should we use to get values in actual params a,b,c inside the function?Cooe
@Cooe .call and .apply do the same thing, just in a different way: test.call(null, 1, 2, 3); or test.call(null, [1, 2, 3]); will both set a = 1, b = 2, and c = 3.Bushranger
@Bushranger yes thanks.. that was a silly comment from me..I was thinking that .call sends params to the arguments local var only..Cooe
@Bushranger Is it possible to use .call or .apply or anything in this manner abc(10,20).call(paramObj).I am stripping out a function written in onClick attrib of a button & then have to call it with an extra param.Function is written like return abc(10,20).The extra param could be a string or an object etc.Cooe
return abc.call(null, 10, 20, paramObj) But if you are not modifying the context of the fn, there is no need for .call: abc(10, 20, paramObj)Bushranger
@Bushranger this is a very clear explanation, thanks a lot.Collector
Did you forget to declare arguments in return function( /*here*/ ) {...?Faso
Nope, arguments is a special object available inside funcitons. See: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Bushranger
T
525

They all attach this into function (or object) and the difference is in the function invocation (see below).

call attaches this into function and executes the function immediately:

var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
person.hello.call({ name: "Jim Smith" }, "world"); // output: "Jim Smith says hello world"

bind attaches this into function and it needs to be invoked separately like this:

var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world");  // output: Jim Smith says hello world"

or like this:

...    
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc();  // output: Jim Smith says hello world"

apply is similar to call except that it takes an array-like object instead of listing the arguments out one at a time:

function personContainer() {
  var person = {  
     name: "James Smith",
     hello: function() {
       console.log(this.name + " says hello " + arguments[1]);
     }
  }
  person.hello.apply(person, arguments);
}
personContainer("world", "mars"); // output: "James Smith says hello mars", note: arguments[0] = "world" , arguments[1] = "mars"                                     
Transvalue answered 10/8, 2015 at 14:50 Comment(4)
Does this mean the difference is that Bind is a Closure?Divisionism
You just taught me about arguments feature used inside a function through your code snippet. It is advisable to mention "use strict" to avoid overriding such reserved keywords. +1.Bekki
@Max agreed; I've submitted an edit wherein "this" is wrong or makes no sense until we use bind/call/applyDecisive
Thanks for the improvement suggestions. I edited my answer a bit. @Decisive Your suggestion had some inaccuracies so couldn't approve it, but did my own edits in the answer. Hopefully it is now more comprehensive.Transvalue
G
327

Answer in SIMPLEST form

  • Call invokes the function and allows you to pass in arguments one by one.
  • Apply invokes the function and allows you to pass in arguments as an array.
  • Bind returns a new function, allowing you to pass in a this array and any number of arguments.

Apply vs. Call vs. Bind Examples

Call

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}

say.call(person1, 'Hello'); // Hello Jon Kuperman
say.call(person2, 'Hello'); // Hello Kelly King

Apply

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}

say.apply(person1, ['Hello']); // Hello Jon Kuperman
say.apply(person2, ['Hello']); // Hello Kelly King

Bind

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say() {
    console.log('Hello ' + this.firstName + ' ' + this.lastName);
}

var sayHelloJon = say.bind(person1);
var sayHelloKelly = say.bind(person2);

sayHelloJon(); // Hello Jon Kuperman
sayHelloKelly(); // Hello Kelly King

When To Use Each

Call and apply are pretty interchangeable. Just decide whether it’s easier to send in an array or a comma separated list of arguments.

I always remember which one is which by remembering that Call is for comma (separated list) and Apply is for Array.

Bind is a bit different. It returns a new function. Call and Apply execute the current function immediately.

Bind is great for a lot of things. We can use it to curry functions like in the above example. We can take a simple hello function and turn it into a helloJon or helloKelly. We can also use it for events like onClick where we don’t know when they’ll be fired but we know what context we want them to have.

Reference: codeplanet.io

Grier answered 12/10, 2017 at 2:47 Comment(4)
In call and apply, does it follow that if you don't have a this inside the method, then you would assign the first argument as a null?Appendix
@DaryllSantos, According to MDN:thisArg Optional. The value of this provided for the call to a function. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode , null and undefined will be replaced with the global object and primitive values will be converted to objects. So if you don't use this in the function it doesn't matter.Grier
call = = comma, apply == array was a nice little memorization trickLegist
var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon Kuperman Works perfectly fine and outputs VM128:4 Hello Jon KupermanHame
P
273

I created this comparison between function objects, function calls, call/apply and bind a while ago:

enter image description here

.bind allows you to set the this value now while allowing you to execute the function in the future, because it returns a new function object.

Pancho answered 6/2, 2019 at 20:42 Comment(0)
W
84

TL;DR:

In simple words, bind creates the function, call and apply executes the function whereas apply expects the parameters in array

Full Explanation

Assume we have multiplication function

function multiplication(a,b){
console.log(a*b);
}

Lets create some standard functions using bind

var multiby2 = multiplication.bind(this,2);

Now multiby2(b) is equal to multiplication(2,b);

multiby2(3); //6
multiby2(4); //8

What if I pass both the parameters in bind

var getSixAlways = multiplication.bind(this,3,2);

Now getSixAlways() is equal to multiplication(3,2);

getSixAlways();//6

even passing parameter returns 6; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

This create a new multiplication function and assigns it to magicMultiplication.

Oh no, we are hiding the multiplication functionality into magicMultiplication.

calling magicMultiplication returns a blank function b()

on execution it works fine magicMultiplication(6,5); //30

How about call and apply?

magicMultiplication.call(this,3,2); //6

magicMultiplication.apply(this,[5,2]); //10

Winglet answered 10/6, 2015 at 18:4 Comment(4)
Very well explained!Tailored
+1 for "In simple words, bind creates the function, call and apply executes the function whereas apply expects the parameters in array"Mauritius
What is function b, and why is it blank?Cove
@DavidSpector, it is not function b. It is a function that takes an argument named 'b' because of how the function "multiplication" was defined with 'a' and 'b' as arguments. Hope that helps!Parenthesize
G
58

It allows to set the value for this independent of how the function is called. This is very useful when working with callbacks:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(sayHello.bind(obj), 1000);

To achieve the same result with call would look like this:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
Grams answered 16/3, 2013 at 21:45 Comment(4)
Usage of .bind() like you've showed before is incorrect. When you use fn.bind(obj) other function will be returned (not that you've create before). And there are no abilities to change value of this inside of binded function. Mostly this is used for callbacks this insurance. But in yours example - there are no differences in result. But fn !== fn.bind(obj); Notice that.Teece
@InviS I don't understand your comment - why is there no different?Grams
The difference in call and apply is. in call you pass arguments as comma separated strings, while in apply you can pass arguments in form of array. rest the are same.Demiurge
comma separated strings?? just pass arguments as comma separated !!Towage
C
48

The main concept behind all these methods is Function borrowing.

Function borrowing allows us to use the methods of one object on a different object without having to make a copy of that method and maintain it in two separate places. It is accomplished through the use of .call(), .apply(), or .bind(), all of which exist to explicitly set this on the method we are borrowing.

  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.

Below is an example of all this methods:

let name = {
    firstName: "Arham",
    lastName: "Chowdhury",
}

printFullName = function(hometown, company) {
    console.log(`${this.firstName} ${this.lastName}, ${hometown}, ${company}`);
}

CALL

the first argument e.g name inside call method is always a reference to (this) variable and latter will be function variable:

printFullName.call(name, "Mumbai", "Taufa"); //Arham Chowdhury, Mumbai, Taufa

APPLY

apply() method is same as the call() method, the only difference is that, the function arguments are passed in array list:

printFullName.apply(name, ["Mumbai", "Taufa"]); //Arham Chowdhury, Mumbai, Taufa

BIND

bind() method is same as call() except that ,the bind() returns a function that can be used later by invoking it — it isn't called automatically immediately:

let printMyName = printFullName.bind(name, "Mumbai", "Taufa");

printMyName(); //Arham Chowdhury, Mumbai, Taufa

printMyName() is the function which invokes the function.

A playground on Codepen.io.

Cornwallis answered 28/5, 2020 at 6:51 Comment(6)
this is a very nice explanationArgue
Thankyou @DarioushPDCornwallis
Thanks a bunch for this nice explanationAgave
This is well explained. Thanks @ArhamChowdhuryTourism
What happens if I pass array to call method ? as I checked it works fine. Can you please explain it.Dailey
@Dailey "call" would not be a good option to use for argument passed as an array. In the above example if you use "call" with an array it would append "undefined" in the end. If there is more then one argument expected then "undefined" would be more.Cornwallis
W
38

Both Function.prototype.call() and Function.prototype.apply() call a function with a given this value, and return the return value of that function.

Function.prototype.bind(), on the other hand, creates a new function with a given this value, and returns that function without executing it.

So, let's take a function that looks like this :

var logProp = function(prop) {
    console.log(this[prop]);
};

Now, let's take an object that looks like this :

var Obj = {
    x : 5,
    y : 10
};

We can bind our function to our object like this :

Obj.log = logProp.bind(Obj);

Now, we can run Obj.log anywhere in our code :

Obj.log('x'); // Output : 5
Obj.log('y'); // Output : 10

Where it really gets interesting, is when you not only bind a value for this, but also for for its argument prop :

Obj.logX = logProp.bind(Obj, 'x');
Obj.logY = logProp.bind(Obj, 'y');

We can now do this :

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
Whitleather answered 18/1, 2016 at 3:59 Comment(0)
S
28

bind: It binds the function with provided value and context but it does not executes the function. To execute function you need to call the function.

call: It executes the function with provided context and parameter.

apply: It executes the function with provided context and parameter as array.

Snowcap answered 22/11, 2017 at 17:31 Comment(1)
simple and humble!Ewe
I
21

Here is one good article to illustrate the difference among bind(), apply() and call(), summarize it as below.

  • bind() allows us to easily set which specific object will be bound to this when a function or method is invoked.

    // This data variable is a global variable​
    var data = [
        {name:"Samantha", age:12},
        {name:"Alexis", age:14}
    ]
    var user = {
        // local data variable​
        data    :[
            {name:"T. Woods", age:37},
            {name:"P. Mickelson", age:43}
        ],
        showData:function (event) {
            var randomNum = ((Math.random () * 2 | 0) + 1) - 1; // random number between 0 and 1​
            console.log (this.data[randomNum].name + " " + this.data[randomNum].age);
        }
    }
    
    // Assign the showData method of the user object to a variable​
    var showDataVar = user.showData;
    showDataVar (); // Samantha 12 (from the global data array, not from the local data array)​
    /*
    This happens because showDataVar () is executed as a global function and use of this inside 
    showDataVar () is bound to the global scope, which is the window object in browsers.
    */
    
    // Bind the showData method to the user object​
    var showDataVar = user.showData.bind (user);
    // Now the we get the value from the user object because the this keyword is bound to the user object​
    showDataVar (); // P. Mickelson 43​
    
  • bind() allow us to borrow methods

    // Here we have a cars object that does not have a method to print its data to the console​
    var cars = {
        data:[
           {name:"Honda Accord", age:14},
           {name:"Tesla Model S", age:2}
       ]
    }
    
    // We can borrow the showData () method from the user object we defined in the last example.​
    // Here we bind the user.showData method to the cars object we just created.​
    cars.showData = user.showData.bind (cars);
    cars.showData (); // Honda Accord 14​
    

    One problem with this example is that we are adding a new method showData on the cars object and we might not want to do that just to borrow a method because the cars object might already have a property or method name showData. We don’t want to overwrite it accidentally. As we will see in our discussion of Apply and Call below, it is best to borrow a method using either the Apply or Call method.

  • bind() allow us to curry a function

    Function Currying, also known as partial function application, is the use of a function (that accept one or more arguments) that returns a new function with some of the arguments already set.

    function greet (gender, age, name) {
        // if a male, use Mr., else use Ms.​
        var salutation = gender === "male" ? "Mr. " : "Ms. ";
        if (age > 25) {
            return "Hello, " + salutation + name + ".";
        }else {
            return "Hey, " + name + ".";
        }
     }
    

    We can use bind() to curry this greet function

    // So we are passing null because we are not using the "this" keyword in our greet function.
    var greetAnAdultMale = greet.bind (null, "male", 45);
    
    greetAnAdultMale ("John Hartlove"); // "Hello, Mr. John Hartlove."
    
    var greetAYoungster = greet.bind (null, "", 16);
    greetAYoungster ("Alex"); // "Hey, Alex."​
    greetAYoungster ("Emma Waterloo"); // "Hey, Emma Waterloo."
    
  • apply() or call() to set this value

    The apply, call, and bind methods are all used to set the this value when invoking a method, and they do it in slightly different ways to allow use direct control and versatility in our JavaScript code.

    The apply and call methods are almost identical when setting the this value except that you pass the function parameters to apply () as an array, while you have to list the parameters individually to pass them to the call () method.

    Here is one example to use call or apply to set this in the callback function.

    // Define an object with some properties and a method​
    // We will later pass the method as a callback function to another function​
    var clientData = {
        id: 094545,
        fullName: "Not Set",
        // setUserName is a method on the clientData object​
        setUserName: function (firstName, lastName)  {
            // this refers to the fullName property in this object​
            this.fullName = firstName + " " + lastName;
        }
    };
    
    function getUserInput (firstName, lastName, callback, callbackObj) {
         // The use of the Apply method below will set the "this" value to callbackObj​
         callback.apply (callbackObj, [firstName, lastName]);
    }
    
    // The clientData object will be used by the Apply method to set the "this" value​
    getUserInput ("Barack", "Obama", clientData.setUserName, clientData);
    // the fullName property on the clientData was correctly set​
    console.log (clientData.fullName); // Barack Obama
    
  • Borrow functions with apply or call

    • Borrow Array methods

      Let’s create an array-like object and borrow some array methods to operate on the our array-like object.

      // An array-like object: note the non-negative integers used as keys​
      var anArrayLikeObj = {0:"Martin", 1:78, 2:67, 3:["Letta", "Marieta", "Pauline"], length:4 };
      
       // Make a quick copy and save the results in a real array:
       // First parameter sets the "this" value​
       var newArray = Array.prototype.slice.call (anArrayLikeObj, 0);
       console.log (newArray); // ["Martin", 78, 67, Array[3]]​
      
       // Search for "Martin" in the array-like object​
       console.log (Array.prototype.indexOf.call (anArrayLikeObj, "Martin") === -1 ? false : true); // true​
      

      Another common case is that convert arguments to array as following

        // We do not define the function with any parameters, yet we can get all the arguments passed to it​
       function doSomething () {
          var args = Array.prototype.slice.call (arguments);
          console.log (args);
       }
      
       doSomething ("Water", "Salt", "Glue"); // ["Water", "Salt", "Glue"]
      
    • Borrow other methods

      var gameController = {
           scores  :[20, 34, 55, 46, 77],
           avgScore:null,
           players :[
                {name:"Tommy", playerID:987, age:23},
                {name:"Pau", playerID:87, age:33}
           ]
       }
       var appController = {
           scores  :[900, 845, 809, 950],
           avgScore:null,
           avg     :function () {
                   var sumOfScores = this.scores.reduce (function (prev, cur, index, array) {
                        return prev + cur;
               });
               this.avgScore = sumOfScores / this.scores.length;
           }
         }
         // Note that we are using the apply () method, so the 2nd argument has to be an array​
         appController.avg.apply (gameController);
         console.log (gameController.avgScore); // 46.4​
         // appController.avgScore is still null; it was not updated, only gameController.avgScore was updated​
         console.log (appController.avgScore); // null​
      
  • Use apply() to execute variable-arity function

The Math.max is one example of variable-arity function,

// We can pass any number of arguments to the Math.max () method​
console.log (Math.max (23, 11, 34, 56)); // 56

But what if we have an array of numbers to pass to Math.max? We cannot do this:

var allNumbers = [23, 11, 34, 56];
// We cannot pass an array of numbers to the the Math.max method like this​
console.log (Math.max (allNumbers)); // NaN

This is where the apply () method helps us execute variadic functions. Instead of the above, we have to pass the array of numbers using apply () thus:

var allNumbers = [23, 11, 34, 56];
// Using the apply () method, we can pass the array of numbers:
console.log (Math.max.apply (null, allNumbers)); // 56
Inmesh answered 8/4, 2016 at 6:45 Comment(0)
S
12

The basic difference between Call, Apply and Bind are:

Bind will be used if you want your execution context to come later in the picture.

Ex:

var car = { 
  registrationNumber: "007",
  brand: "Mercedes",

  displayDetails: function(ownerName){
    console.log(ownerName + ' this is your car ' + '' + this.registrationNumber + " " + this.brand);
  }
}
car.displayDetails('Nishant'); // **Nishant this is your car 007 Mercedes**

Let's say i want use this method in some other variable

var car1 = car.displayDetails('Nishant');
car1(); // undefined

To use the reference of car in some other variable you should use

var car1 = car.displayDetails.bind(car, 'Nishant');
car1(); // Nishant this is your car 007 Mercedes

Let's talk about more extensive use of bind function

var func = function() {
 console.log(this)
}.bind(1);

func();
// Number: 1

Why? Because now func is bind with Number 1, if we don't use bind in that case it will point to Global Object.

var func = function() {
 console.log(this)
}.bind({});

func();
// Object

Call, Apply are used when you want to execute the statement at the same time.

var Name = { 
    work: "SSE",
    age: "25"
}

function displayDetails(ownerName) {
    console.log(ownerName + ", this is your name: " + 'age' + this.age + " " + 'work' + this.work);
}
displayDetails.call(Name, 'Nishant')
// Nishant, this is your name: age25 workSSE

// In apply we pass an array of arguments
displayDetails.apply(Name, ['Nishant'])
// Nishant, this is your name: age25 workSSE
Streaming answered 10/8, 2019 at 6:35 Comment(0)
W
11

call/apply executes function immediately:

func.call(context, arguments);
func.apply(context, [argument1,argument2,..]);

bind doesn't execute function immediately, but returns wrapped apply function (for later execution):

function bind(func, context) {
    return function() {
        return func.apply(context, arguments);
    };
}
Wraparound answered 7/2, 2017 at 19:34 Comment(0)
R
9

Call apply and bind. and how they are different.

Lets learn call and apply using any daily terminology.

You have three automobiles your_scooter , your_car and your_jet which start with the same mechanism (method). We created an object automobile with a method push_button_engineStart.

var your_scooter, your_car, your_jet;
var automobile = {
        push_button_engineStart: function (runtime){
        console.log(this.name + "'s" + ' engine_started, buckle up for the ride for ' + runtime + " minutes");
    }
}

Lets understand when is call and apply used. Lets suppose that you are an engineer and you have your_scooter, your_car and your_jet which did not come with a push_button_engine_start and you wish to use a third party push_button_engineStart.

If you run the following lines of code, they will give an error. WHY?

//your_scooter.push_button_engineStart();
//your_car.push_button_engineStart();
//your_jet.push_button_engineStart();


automobile.push_button_engineStart.apply(your_scooter,[20]);
automobile.push_button_engineStart.call(your_jet,10);
automobile.push_button_engineStart.call(your_car,40);

So the above example is successfully gives your_scooter, your_car, your_jet a feature from automobile object.

Let's dive deeper Here we will split the above line of code. automobile.push_button_engineStart is helping us to get the method being used.

Further we use apply or call using the dot notation. automobile.push_button_engineStart.apply()

Now apply and call accept two parameters.

  1. context
  2. arguments

So here we set the context in the final line of code.

automobile.push_button_engineStart.apply(your_scooter,[20])

Difference between call and apply is just that apply accepts parameters in the form of an array while call simply can accept a comma separated list of arguments.

what is JS Bind function?

A bind function is basically which binds the context of something and then stores it into a variable for execution at a later stage.

Let's make our previous example even better. Earlier we used a method belonging to the automobile object and used it to equip your_car, your_jet and your_scooter. Now lets imagine we want to give a separate push_button_engineStart separately to start our automobiles individually at any later stage of the execution we wish.

var scooty_engineStart = automobile.push_button_engineStart.bind(your_scooter);
var car_engineStart = automobile.push_button_engineStart.bind(your_car);
var jet_engineStart = automobile.push_button_engineStart.bind(your_jet);


setTimeout(scooty_engineStart,5000,30);
setTimeout(car_engineStart,10000,40);
setTimeout(jet_engineStart,15000,5);

still not satisfied?

Let's make it clear as teardrop. Time to experiment. We will go back to call and apply function application and try storing the value of the function as a reference.

The experiment below fails because call and apply are invoked immediately, hence, we never get to the stage of storing a reference in a variable which is where bind function steals the show

var test_function = automobile.push_button_engineStart.apply(your_scooter);

Raker answered 27/3, 2017 at 17:21 Comment(0)
R
9

Syntax

  • call(thisArg, arg1, arg2, ...)
  • apply(thisArg, argsArray)
  • bind(thisArg[, arg1[, arg2[, ...]]])

Here

  • thisArg is the object
  • argArray is an array object
  • arg1, arg2, arg3,... are additional arguments

function printBye(message1, message2){
    console.log(message1 + " " + this.name + " "+ message2);
}

var par01 = { name:"John" };
var msgArray = ["Bye", "Never come again..."];

printBye.call(par01, "Bye", "Never come again...");
//Bye John Never come again...

printBye.call(par01, msgArray);
//Bye,Never come again... John undefined

//so call() doesn't work with array and better with comma seperated parameters 

//printBye.apply(par01, "Bye", "Never come again...");//Error

printBye.apply(par01, msgArray);
//Bye John Never come again...

var func1 = printBye.bind(par01, "Bye", "Never come again...");
func1();//Bye John Never come again...

var func2 = printBye.bind(par01, msgArray);
func2();//Bye,Never come again... John undefined
//so bind() doesn't work with array and better with comma seperated parameters
Regalia answered 16/6, 2017 at 14:19 Comment(0)
C
6

JavaScript Call()

const person = {
    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.call(anotherPerson,1,2)

JavaScript apply()

    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.apply(anotherPerson,[1,2])

**call and apply function are difference call take separate argument but apply take array like:[1,2,3] **

JavaScript bind()

    name: "Lokamn",
    dob: 12,
    anotherPerson: {
        name: "Pappu",
        dob: 12,
        print2: function () {
            console.log(this)
        }
    }
}

var bindFunction = person.anotherPerson.print2.bind(person)
 bindFunction()
Cristiecristin answered 14/3, 2020 at 11:56 Comment(0)
H
5

Call: call invokes the function and allows you to pass arguments one by one

Apply: Apply invokes the function and allows you to pass arguments as an array

Bind: Bind returns a new function, allowing you to pass in a this array and any number of arguments.

var person1 = {firstName: 'Raju', lastName: 'king'};
var person2 = {firstName: 'chandu', lastName: 'shekar'};

function greet(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}
function greet2(greeting) {
        console.log( 'Hello ' + this.firstName + ' ' + this.lastName);
    }


greet.call(person1, 'Hello'); // Hello Raju king
greet.call(person2, 'Hello'); // Hello chandu shekar



greet.apply(person1, ['Hello']); // Hello Raju king
greet.apply(person2, ['Hello']); // Hello chandu shekar

var greetRaju = greet2.bind(person1);
var greetChandu = greet2.bind(person2);

greetRaju(); // Hello Raju king
greetChandu(); // Hello chandu shekar
Hertford answered 7/2, 2019 at 8:25 Comment(0)
S
5

call() :-- Here we pass the function arguments individually, not in an array format

var obj = {name: "Raushan"};

var greeting = function(a,b,c) {
    return "Welcome "+ this.name + " to "+ a + " " + b + " in " + c;
};

console.log(greeting.call(obj, "USA", "INDIA", "ASIA"));

apply() :-- Here we pass the function arguments in an array format

var obj = {name: "Raushan"};

var cal = function(a,b,c) {
    return this.name +" you got " + a+b+c;
};

var arr =[1,2,3];  // array format for function arguments
console.log(cal.apply(obj, arr)); 

bind() :--

       var obj = {name: "Raushan"};

       var cal = function(a,b,c) {
            return this.name +" you got " + a+b+c;
       };

       var calc = cal.bind(obj);
       console.log(calc(2,3,4));
Siliceous answered 21/12, 2019 at 20:24 Comment(0)
B
3

Imagine, bind is not available. you can easily construct it as follow :

var someFunction=...
var objToBind=....

var bindHelper =  function (someFunction, objToBind) {
    return function() {
        someFunction.apply( objToBind, arguments );
    };  
}

bindHelper(arguments);
Billposter answered 20/8, 2016 at 10:42 Comment(0)
H
3
    function sayHello() {
            //alert(this.message);
            return this.message;
    }
    var obj = {
            message: "Hello"
    };

    function x(country) {
            var z = sayHello.bind(obj);
            setTimeout(y = function(w) {
//'this' reference not lost
                    return z() + ' ' + country + ' ' + w;
            }, 1000);
            return y;
    }
    var t = x('India')('World');
    document.getElementById("demo").innerHTML = t;
Hemiterpene answered 15/12, 2017 at 9:49 Comment(0)
E
2

Use bind for future calls to the function. Both apply and call invoke the function.

bind() also allows for additional arguments to be perpended to the args array.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind

Ealdorman answered 12/8, 2020 at 20:43 Comment(0)
C
1

The first difference between call(), apply(), and bind() methods in JavaScript is their time of execution! call() and apply() being similar are executed instantly, whereas, bind() creates a new function which we have to explicitly call at any later point of time!

Another difference is, that while passing arguments, call() allows us to pass one by one separated by commas, apply() allows us to pass as an array of arguments, and bind() allows us to do both!

I have attached the example code below!

const person = {
    fullName : function (randomMessage) {
        return `Hello, ${this.firstName} ${this.lastName} ${randomMessage}`;
    }
}

const personOne = {
    firstName : "John",
    lastName : "Doe"
}

const personTwo = {
    firstName : "Jack",
    lastName : "Adhikari"
}

let fullNameBind = person.fullName.bind(personOne, "--Binding");
let fullNameCall = person.fullName.call({firstName : "Sarah", lastName: "Holmes"}, "--Calling");
let fullNameApply = person.fullName.apply(personTwo, ["--Applying"]);

console.log(fullNameBind());
console.log(fullNameCall);
console.log(fullNameApply);
Camarillo answered 3/7, 2022 at 10:56 Comment(0)
C
0

In simple terms, all methods are used to set the context(this) explicitly in the regular function

Call: call invokes the function on given context and allows to pass arguments one by one

Apply: apply invokes the function on given context and allows to pass arguments as an array

Bind: bind returns a new function by setting the provided context, and allows to pass arguments one by one

Notes:

  1. Call and Apply both are similar only difference is the way they expect arguments
  2. The mentioned methods do not work with arrow function
Caprifoliaceous answered 5/2, 2022 at 11:11 Comment(0)
B
-1

I think the same places of them are: all of them can change the this value of a function.The differences of them are: the bind function will return a new function as a result; the call and apply methods will execute the function immediately, but apply can accept a array as params,and it will parse the array separated.And also, the bind function can be Currying.

Booking answered 15/4, 2016 at 9:36 Comment(0)
E
-3

bind function should be use when we want to assign a function with particular context for eg.

var demo = {
           getValue : function(){ 
             console.log('demo object get value       function') 
            }
           setValue : function(){  
              setTimeout(this.getValue.bind(this),1000)           
           }
 }

in above example if we call demo.setValue() function and pass this.getValue function directly then it doesn't call demo.setValue function directly because this in setTimeout refers to window object so we need to pass demo object context to this.getValue function using bind. it means we only passing function with the context of demo object not actully calling function.

Hope u understand .

for more information please refer javascript bind function know in detail

Entoil answered 25/12, 2016 at 6:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.