I saw an interview question a few days ago, and the question was like this:
Could you please tell me your understanding of apply, call, and bind in JavaScript?
First of all, apply and call are clichés, but as for bind, I was stunned for a moment, because this word is a frequently used method in jquery, which is used to bind events to DOM elements.
In order to understand this strange yet familiar bind, I googled and found that this method is natively implemented in JavaScript version 1.8.5. Currently, IE9, ff4, and chrome7 support this method, but opera and safari do not support it (explanation on MDN).
The function of bind is similar to that of apply and call, both of which change the execution context of the function, which is the point of the this keyword during runtime. But the usage is slightly different. A function can be executed later after being bound.
An example is as follows:
var person = {
name: 'Andrew',
job: 'web front end developer',
gender: 'male',
sayHello: function() {
return 'Hi, I am ' this.name ', a ' this.job;
}
}
console.log(person.sayHello()); // Hi, I am Andrew, a web front end developer
var anotherGuySayHello = person .sayHello.bind({
name:'Alex',
job: 'back end C# developer'
});
console.log(anotherGuySayHello()); // Hi, I am Alex, a back end C# developer
Another example with parameters:
function add(arg1, arg2, arg3, arg4) {
return arg1 ' ' arg2 ' ' arg3 ' ' arg4;
}
var addMore = add. bind({}, 'a', 'b');
console.log(addMore('c', 'd')); // a b c d
If your browser This method is not supported for the time being, but you think it is cool and want to use it. MDN also provides a reference implementation. This implementation is very interesting. The code is as follows:
if(!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if( typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var fSlice = Array.prototype. slice,
aArgs = fSlice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply (this instanceof fNOP ? this : oThis || window, aArgs.concat(fSlice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP ();
return fBound;
};
}
The last few lines of code are through the prototype chain, where fBound is a subclass that calls the bind function. Why is this so? For implementation, you can carefully look at the part fBound = function(){ return ... }, where this is determined at runtime. The main consideration here is if you use new to call the function (constructor method).
The following example can illustrate this point well. For the convenience of explanation, this example comes directly from MDN:
function Point(x,y) {
this.x = x;
this.y = y;
}
Point.prototype .toString = function() {
return this.x ',' this.y;
};
var p = new Point(1, 2);
p.toString(); / / 1,2
var emptyObj = {};
var YAxisPoint = Point.bind(emptyObj, 0);
var axisPoint = new YAxisPoint(5);
axisPoint.toString(); / / 0, 5
axisPoint instanceof Point; // true
axisPoint instanceof YAxisPoint; // true
The article link is given at the end for your further understanding
MDN: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
- MSDN: http://msdn.microsoft.com/en-us/library/ff841995(v=vs.94).aspx