What are some practical use cases where call, apply, and/or bind would be useful?
Hi,
Can I get somewhat of an ELI5 explaination of bind vs call vs apply?
I'm still confused as to what these 3 do.
Even in the context of having a simple add function would be great.
Thanks!
call calls a function with individual arguments:
fn.call( thisArg, 1, 2, 3 ); // fn( 1, 2, 3 ); with `this` in fn set to `thisArg`
apply calls a function with an array of arguments:
fn.apply( thisArg, [ 1, 2, 3 ] ); // fn( 1, 2, 3 ); with `this` in fn set to `thisArg`
bind doesn't call the function at all, but binds scope and arguments to a function so that when you call the resulting function the original one is called:
var newFn = fn.bind( thisArg, 1, 2, 3 ); // fn doesn't run yet
newFn(); // calls fn.call( thisArg, 1, 2, 3 );
newFn( 4 ); // calls fn.call( thisArg, 1, 2, 3, 4 );
So call vs apply just comes down to how you have your data (well that and call is much faster). Use bind when you want to do something later
You should read each page on MDN in full:
Function.prototype.apply()
Function.prototype.call()
Function.prototype.bind()
call and apply do essentially the same thing: they let you call a function with complete control over its this value and its argument list. Normally when you invoke a function you do not get to control what this will be inside the function; that's determined by the shape of the expression on the left hand side of the function call operator (i.e. the parentheses). apply takes the argument list as an array or an array-like object, whereas call takes a series of arguments directly. apply is often used when you want to write a wrapper around another function, because you can pass the arguments variable for the array of arguments, which means the called function receives whatever arguments the wrapper function had.
bind performs partial application, i.e. it fixes or binds the this value and arguments of a function. It doesn't call the function, but returns a bound version of the function. For example:
var fixed = foo.bind(someObject);
fixed is now a version of the function foo that when called will have its this value set to someObject. fixed can also take arguments, which are passed on normally, e.g. fixed('str') calls foo('str') except inside foo, this is set to someObject instead of what it would normally be (in this case, the global object.) If any bound parameters were specified, they come before any given when the bound function is called.
Videos
I understand how they work but I've just never seen the need to use them. I barely even use this, except in vue.
Am I just doing things wrong?
I know that they could be used to manipulate what the this keyword points to or means. but what I can't seem to get is their use cases and when exactly are they relevant.
Do you often use the 'bind' function? If you use it often, what do you usually use it for?
I know that historically .call() accepts arguments individually, and that .apply() accepts all arguments at the same time in an array. But after the spread operator was introduced is .apply() purely redundant? It seems like any code written like this
f.apply(thisObj, argArray)
could instead be written like this
f.call(thisObj, ...argArray)
and you would get the exact same result (except that the former might run slightly faster). So is there any time that you would be forced to use apply instead of call? Or does apply only exist in the modern day for historical reasons and slight performance increases in some cases?
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.
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"
so bascially there are two codes which return the same output
code -1
const person = {
name: "John",
greet: function() {
setTimeout(function() {
console.log(this.name);
}.bind(this), 1000); // This will immediately invoke the function instead of waiting 1 second
}
};
person.greet();output - john
code -2
const person = {
name: "John",
greet: function() {
setTimeout(function() {
console.log(this.name);
}.call(this), 1000);
}
};
person.greet();output - john
now i know how call and bind works call attaches a new this context while bind does the same thing and creates a new function at the same time
chatgpt says they are different i sort of doubt it
here is the answer of chatgpt
You're right! It may work in some environments like the browser console or terminal, but the behavior is not ideal or recommended for use with `setTimeout`.
Let me explain why:
### When you use `call`:
In your code, using `call` within `setTimeout` does immediately invoke the function. The function gets executed before the `setTimeout` delay even starts, which means it’s not truly being delayed. However, depending on the environment, you may still see the expected behavior because the execution of the `setTimeout` handler itself could be deferred just enough to make it appear as though it worked correctly.
Here's why it shouldn't be used:
1. **Immediate Execution**: `call` immediately calls the function, passing its result to `setTimeout`. So, the function is run immediately, and the delayed execution via `setTimeout` is bypassed.
2. **Expected Behavior**: Using `bind` is more appropriate because it creates a new function that maintains the proper `this` context and will be executed after the delay.
### Example with `call`:
```javascript
const person = {
name: "John",
greet: function() {
setTimeout(function() {
console.log(this.name); // Will immediately log "John"
}.call(this), 1000); // Function is invoked immediately
}
};
person.greet();
```
Even though the `call` might seem to work in your environment, you won't get the 1-second delay. It will execute instantly because `call` runs the function immediately. You’re essentially passing `undefined` to `setTimeout`.
### Example with `bind` (correct):
```javascript
const person = {
name: "John",
greet: function() {
setTimeout(function() {
console.log(this.name); // `this` will now correctly refer to `person`
}.bind(this), 1000); // Function is bound but not invoked immediately
}
};
person.greet();
```
Using `bind` ensures that `this` refers to `person`, and the function is called after the 1-second delay.
### Conclusion:
While it may appear to work in some environments due to execution timing differences, `call` is not the correct method for use with `setTimeout` in this scenario. The correct approach is to use `bind`, which delays execution while maintaining the correct context for `this`.
now i kind of doubt whether chatgpt is right or not
so good people of learnjavascript plz clear it out for me
edit : "chatgpt has made me addicted to quick answers. thats why instead of going through docs i came straight here
as some one pointed here testing it or just reading the docs could have solved this question .
i am breaking this habit right now thanks everyone here for being patient with me and calling out my errors "
<Box
onClick={toggleBox.bind(null, index)}>
</Box> I heard it's because you don't re-create the function if you do this inside onClick, but since you're also re-creating the arrow function toggleBox on each render, what should you do to ensure the best performance? Should you use useCallback and then use toggleBox.bind(null, index) inside onClick?
I am giving interviews for the frontend position and in every interview, they seem to just ask about all these concepts. I work currently in an eCommerce company, we use Vue js as the framework but in my 2 yrs of experience I have never used object-oriented concepts of javascript, rather we use functional programming. Is object-oriented programming javascript really used everywhere or these are some generic questions that are being asked in interviews?
edit: call apply bind were example for interview questions, i meant advanced concepts like prototype inheritance and all
Hi! I'm trying to understand Bind vs Call. I do know that Call will execute a function where you can reference an object so .this refers to who calls, and also add arguments, just like Apply with the difference of an array being passed.
I'm trying to understand Bind though. From what I've gathered it is used to store the returned function for later use? I've seen the button examples, and even timeout examples but I don't see the difference in result.
const person = {
name: "John Doe"
};
function getName() {
return this.name;
}
const myFunCall = getName.call(person);
setTimeout(function(){alert(myFunCall);}, 2000);
Gives me the same result when using bind:
const person = {
name: "John Doe"
};
function getName() {
return this.name;
}
const myFunBind = getName.bind(person);
setTimeout(function(){alert(myFunBind());}, 2000);
From what I've gathered it is used to store the returned function for later use?
Right. So call() calls a function right away. bind() on the other hand is a kind of call(), but it doesn't call the function right away. It takes all the arguments you passed into it, and holds on to them, returning a function that when called, effectively uses call() with those arguments. Think of bind() as:
function bind(func, ...callArguments) { function callFuncWithCall() { return func.call(...callArguments) } return callFuncWithCall}
So its a call() for later.
You can also think of call as:
func.bind(...args)() // calls bind, then calls the return of bind
In your example you're not seeing a difference because you're doing the same thing, one the call way and one the bind way. The difference is in your alert:
alert(myFunCall);// vsalert(myFunBind());
Notice the difference? In the call version you're alerting the value. In the bind version you're calling the value. myFunCall is the return value of getName() whereas myFunBind is a version of the function getName() you have to call to get a value.
They clearly dont give you the same result.
the bind returns a new function where the object you provided is bound to the function to replace any reference of “this” inside the function.
The call is doing the same as bind but it actually also goes ahead and calls the function.
bind:
takes a object to be used as the “this” and optionally any arguments this function use and returns a new function with the “this” and any argument already replaced with the values you provide.
function A(x) { return this.y + x; }
const a = A.bind({y: 30}); const b = A.bind({y: 30}, 7);
a(5) // returns 35 b() // returns 37
call:
Does everything bind does but goes one step further and calls that function immediately.
A.call({y: 30}, 5); // returns 35 A.call({y: 30}, 7); // returns 37
apply:
Does the same as call but takes the function arguments as array instead of comma separated.
A.call({y: 30}, [5]); // returns 35 A.call({y: 30}, [7]); // returns 37