call, apply, bind Detailed

Why change this point?

We know the role bind, call, apply are used to change this point, why do you want to change this point? Consider the following example:

var name="lucy";
let obj={
 name:"martin",
 say:function () {
 console.log(this.name);
 }
};
obj.say(); //martin,this指向obj对象
setTimeout(obj.say,0); //lucy,this指向window对象

Can be observed that, under normal circumstances say this method is directed to call its object obj, and say timer setTimeout method of the window object of this is to point (in the browser), this is because the method say timer is a callback function to be executed, so back to the main stack is executed when performed in the context of the implementation of the global environment, but we need to approach this is to say point to the object obj, so we need to modify the point of this.

apply method

apply accepts two parameters, the first parameter is this point, the second parameter is a function accepts parameters passed in the form of an array, and when the first parameter is null, undefined, and defaults to the window (in browser), use this point to apply the method to change the original function will be executed immediately, and this method is only a temporary change in thi point.

Daily usage: Change this point

Example:

Callbacks associated with this point:

var name="martin";
var obj={
 name:"lucy",
 say:function(year,place){
 console.log(this.name+" is "+year+" born from "+place);
 }
};
var say=obj.say;
setTimeout(function(){
 say.apply(obj,["1996","China"])
} ,0); //lucy is 1996 born from China,this改变指向了obj
say("1996","China") //martin is 1996 born from China,this指向window,说明apply只是临时改变一次this指向

Tip: change the parameters passed in the way

Example:

Selecting the maximum value in the array:

var arr=[1,10,5,8,3];
console.log(Math.max.apply(null, arr)); //10

Which is based on the parameters Math.max function parameter list, such as: Math.max (1,10,5,8,3) in the form of incoming, so we can not directly to the array as a parameter, but the method can apply to an array parameters into parameter list passed, thereby directly selecting the maximum value of the array.

call method

The first parameter of this call is directed to a method, it is passed back a list of parameters (transmission parameters and apply note distinction). When a parameter is null or undefined, expressed point window (in the browser), and apply the same, call only a temporary change once this point, and executed immediately.

Example:

var arr=[1,10,5,8,3];
console.log(Math.max.call(null,arr[0],arr[1],arr[2],arr[3],arr[4])); //10

Adoption of the list passed as a parameter, and apply passed as a parameter array.

bind method

bind method call and is similar to the first parameter is this point, is passed back a list of parameters (parameter list but this can be passed multiple times, one time call must pass all parameters), but this change after the point is not performed immediately, but this function returns a permanent change points.

Example:

var arr=[1,10,5,8,12];
var max=Math.max.bind(null,arr[0],arr[1],arr[2],arr[3])
console.log(max(arr[4])); //12,分两次传参

As can be seen, bind in multiple ways to pass parameters, all the parameters will connect together into the final function of the operating function runs.

Implement bind method (interview questions):

Lite

 Function.prototype.bind=function () {
 var _this=this;
 var context=arguments[0];
 var arg=[].slice.call(arguments,1);
 return function(){
 arg=[].concat.apply(arg,arguments);
 _this.apply(context,arg);
 }
 };

Perfect version

//实现bind方法
 Function.prototype.bind = function(oThis) {
 if (typeof this !== 'function') {
 // closest thing possible to the ECMAScript 5
 // internal IsCallable function
 throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
 }
 var aArgs = Array.prototype.slice.call(arguments, 1),
 fToBind = this,
 fNOP = function() {},
 fBound = function() {
 // this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
 return fToBind.apply(this instanceof fBound
 ? this
 : oThis,
 // 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
 aArgs.concat(Array.prototype.slice.call(arguments)));
 };
 // 维护原型关系
 if (this.prototype) {
 // 当执行Function.prototype.bind()时, this为Function.prototype 
 // this.prototype(即Function.prototype.prototype)为undefined
 fNOP.prototype = this.prototype; 
 }
 // 下行的代码使fBound.prototype是fNOP的实例,因此
 // 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
 fBound.prototype = new fNOP();
 return fBound;
 };
 var arr=[1,11,5,8,12];
 var max=Math.max.bind(null,arr[0],arr[1],arr[2],arr[3]);
 console.log(max(arr[4])); //12

Differences apply, call, bind three

  • All three can change this target pointers to functions.
  • The first three parameters are pointing to this object, if without this parameter or parameter is undefined or null, it defaults to the global window.
  • All three parameters can be transferred, but apply an array, while the call is a list of parameters, and apply a one-time call and pass parameters, and bind can be divided into several times passed.
  • bind binding is a function of the return after this, to facilitate later call; apply, call is executed immediately.

Guess you like

Origin www.cnblogs.com/liutianzeng/p/11515230.html