[JavaScript]-depth understanding of call, as well as apply, bind the difference

A, call

There are two magical call

     1, inheritance (my previous article mentioned implement call by call inheritance, are interested can look. Https://www.cnblogs.com/pengshengguang/p/10547624.html )

     2. Modify function is running this point (to say today)

// a snippet 
var obj = {name: 'PSG'}; 
function Fn (num1, num2) { 
    the console.log (num1 num2 +); 
    the console.log (the this)   
} 
//. 1, Call inside, a first parameters will say this to become the object of 
fn (100, 200); // this point window, num1 = 100, 200 is num2 = 
fn.call (100, 200 is); // this point 100, num1 = 200, num2 undefined = 
fn.call (obj, 100, 200 is); // the this point obj, num1 = 100, 200 is num2 = 

// 2, in a non-strict model, Call which, if the first argument is null, null, undefined will lead to this point window 
fn.call (); // this point window 

// 3, in strict mode, call it, this is who who pass, do not pass, this is undefined 
fn.call (); // this pointing undefined 
fn.call (null); // the this point to null 
fn.call (undefined); // points to the this undefined

 

Two, apply

     1, apply and function call method is exactly the same, are used to change the method and the method of performing this keyword, and in strict mode, non-strict model for the first parameter is null / undefined law in this case It is the same.

     2, with the only difference is the call syntax differences:

// call transfer parameters are separated by commas, a pass in a 
fn.call (obj, arg1, arg2, arg3 .....) 
// Apply transmission parameters is a transmission array of 
fn.apply (obj, [arg1 , arg2, arg3 ....])

 

Three, bind

     1, this method is not compatible in IE6-IE8.

     2, and apply, call the like, are used to change this point, but bind reflects js pretreatment thought.

          -> Pretreatment: fn realization of this change to the results we want, and the parameter object is also ready to use later, can be directly executed.

obj = {name var: 'PSG'}; 
function Fn (num1, num2) { 
    the console.log (num1 num2 +); 
    the console.log (the this); 
} 
fn.call (obj, 100, 200 is); 
fn.bind (obj, 100, 200); // just changed to fn in this obj, and to fn passing two parameters, but this time not to execute the function fn. 
// However, the implementation will bind a return value, the return value is the result of myFn we fn of this change! ! ! 

// So, how to make it perform this function fn, the following wording on the line Solution 
var myFn = fn.bind (obj, 100, 200); 
myFn ();

 

Fourth, in-depth understanding of call

  4.1 If we are to understand the call, we first need to know how the call is to be executed, involving the prototype chain lookup mechanism.

//例如,现在有一个函数fn,我们想改变fn中this的指向,因此我们可以
fn.call(obj);
//上面的代码,其实是首先通过fnl的原型链,找到Function.ptototype中的call方法,然后执行call方法,cal方法中的this,就是fn

  4.2 伪代码模拟实现call方法

Function.prototype.myCall = function(context) {
    //->1、让fn中的this关键字变成context
    this = eval(this.toString().replace("this", context));
    //->2、让fn执行
    this();  
}  

  4.3 经典面试题

// 练习一
function fn1() {console.log(1);}
function fn2() {console.log(2);}
fn1.call(fn2); // ->1    
//原理:首先fn1通过原型链机制找到Function.prototype上的call方法,并且让call方法执行
// 此时call这个方法中的this就是fn1,在call方法执行过程中,让fn1中this关键字变成fn2,然后让fn1执行

fn1.call.call(fn2); // ->2
//原理首先fn1通过原型链机制找到Function.prototype上的call方法,然后再让call方法通过原型找到call方法
// Function.prototype原型上的call(因为fn.call这个东西也是个函数数据类型),在第二次找到call时,让call方法执行,此时
// 的this是fn1.call。

  end

 

Guess you like

Origin www.cnblogs.com/pengshengguang/p/11184378.html