The bind function allows you to set the context with which a function will execute. It takes in a ‘context‘ object and returns a new function which has its context set to the passed in object. The variadic method, which exists on all function objects, provides a workaround for the annoying and elusive ‘this’ context issue in JavaScript.
As web developers; we all nearly need to create references to object methods at some time or the other. The annoying thing is that the original context is uusally lost when we need it most! Let’s see how bind can help in these scenarios.
var obj = {
val: 10,
getVal: function () {
return this.val;
}
};
obj.getVal();
//10
var valGetter = obj.getVal;
valGetter();
//undefined
var boundValGetter = valGetter.bind(obj);
boundValGetter();
//10
The JavaScript bind Function Signature
Function.bind(thisObj, arg1, arg2,...)
thisObj refers to the new context for the function. However if the newly returned function is used as a constructor (i.e. called using the new operator), the this context will be a new empty object as expected.
arg1, arg2,… are extra parameters that are prepended to the list of arguments that the newly bound function is called with. Assuming you declare two arguments in the original bind call and then pass three new arguments to the returned bound function, then the two original bound arguments appear before the three newly passed in arguments.
var fn = function () {};
var bound = fn.bind(window, 1,2);
// equivalent forms
bound(3);
fn.call(window, 1,2,3)
If the bound function is invoked as a constructor, then the bound arguments are still passed on.
How to use bind in JavaScript
The most common application would be to avoid the use of the ‘that = this’ pattern in JavaScript. This is especially the case when you need to pass in context to event handlers, use anonymous functions or do something similar.
var ordExample = {
log : function () {
console.log('logger called');
},
asyncCall : function (callback) {
//...
callback();
},
useAsync : function () {
var that = this;
this.asyncCall(function () {
that.log();
});
}
}
//Bind form
var bindExample = {
log : function () {
console.log('logger called');
},
asyncCall : function (callback) {
//...
callback();
},
useAsync : function () {
this.asyncCall(function () {
this.log();
}.bind(this));
}
}
ordExample.useAsync();
//logger called
bindExample.useAsync();
//logger called
[/code]
As seen from the example above, we can use this in all sort of scenarios – from timers, Ajax callback handlers, event handlers, custom objects etc.
Issues with bind: Unbinding bound functions
You cannot unbind after binding a function; anytime you call the Function.prototype.bind, you get a new function which has its ‘this’ context already prefixed to the pre-supplied value.
var fn = function () {};
console.log(fn.bind(this)===fn.bind(this));
//false
Ben Cowboy Alman has written a Function.protoype.unbind polyfill here.
The other issue is that there is some overhead with using bind; it adds some overhead and is not as optimal as using the ‘this = that‘ approach (variable vs function). Here is a jsperf run for four various bind styles.
So that’s it; now go bind some functions.
Reblogged this on Dinesh Ram Kali..
LikeLike
How does this relate to the apply() method
LikeLike
Thanks Charles,
The apply method invokes the function immediately while setting the context.
Bind returns a new function with the context set to what you want. It is now possible to re-use this function in several places as you wish (not possible with apply).
Please let me know if this explains it.
LikeLike