Call,apply, and bind all change the direction of this

Grammar:

func.call(thisagr,param1,param1,...) func.apply(thisagr,[param1,param1,...] ) func.bind(thisagr,param1,param1,...)Copy the code

1. The call:

The first argument to call is the object to be changed to this

var obj = { name: 'psg' }; function fn(num1, num2) { console.log(num1 + num2); Console. log("this points to :" + this, "num1:" + num1, "num2:" + num2)} fn(100, 200); //this points to window, num1=100, num2=200; fn. Call (100, 200); ////this pointer to 100, num1=200, num2=undefined fn.call(obj, 100, 200); //this points to obj, num1=100, num2=200Copy the code

1.2 In strict mode, this refers to in non-strict mode

In non-strict mode :this is null; undefined, this points to window. In strict mode :this is the same as the one passed; undefined

// Strict mode fn.call(); //this refers to undefined fn.call(null); //this refers to null fn.call(undefined); / / this point to undefinedCopy the code

2. Apply:

Apply is similar to call, but does not use the syntax

Call arguments are comma separated and passed one by one: fn.call (obj, arg1,agr2)

Apply (obj,[agr1, agR2])

var obj1 = { name: 'psg' }; function fn1(num1, num2) { console.log(num1 + num2); Console. log("this points to :" + this, "num1:" + num1, "num2:" + num2)} fn1.call(obj1, 100, 200); fn1.apply(obj1, [100, 200]);Copy the code

3. The bind:

Bind is similar to call in that it has the same syntax, but bind represents js preprocessing

Bind will not execute the function, but will return a value (the return value is a copy of the function)

Preprocessing: the implementation changes fn’s this to the desired result, and also prepares the object’s parameters, when to use, directly execute the line

var obj1 = { name: 'psg' }; function fn1(num1, num2) { console.log(num1 + num2); Console. log("this points to :" + this, "num1:" + num1, "num2:" + num2)} fn1.call(obj1, 100, 200); fn1.bind(obj1, 100, 200); // Bind simply changes this in fn to obj and passes fn two parameters, but does not call fn at this time. // Bind returns a value myFn, which is the result of changing fn's this. var myFn = fn1.bind(obj1, 100, 200); myFn(); // Execute the functionCopy the code

3.1 Manually implement BIND

4. Summary differences:

What is the difference between call and apply?

The syntax varies, and the arguments passed to the function are written differently

Call is different from bind:

1. Perform:

Call, apply changes this execution to execute the function immediately

Bind returns the function after this, but does not execute the function

 

5. Manually simulate call:

Arguments (); / / Add arguments to an array; / / Add arguments to an array; / / Add arguments to an array

1. Change this to add a property to the passed object, point this to the property, then point to the method and delete the property

2. Use arguments to accept arguments passed in

Function.prototype.myCall = function (con) { con = new Object(con) || window || global; //1. With no arguments, point to window con.fun = this; //2. Create an attribute for the target object and bind the function let arr =[]; //3. Create an empty array for (let I = 1; i < arguments.length; i++) { arr.push(arguments[i]); } con.fun(... arr); //4. Run delete con.fun; } var obj = {name: 12} function fn(num1, num2) {console.log("this:" + this); function fn(num1, num2) {console.log("this:" + this); console.log("num1:" + num1); console.log("num2:" + num2); } fn.myCall(100, 200); fn.myCall(obj, 100, 200);Copy the code

 

Method 2: Eval converts the original function to a string and replaces this with the target object

1. Arguments refer to all arguments that a function receives. It is an Array of classes and cannot use the Array method

The first one is this, and then the parameters

  1. Eavl () can take a string STR as an argument and execute it as script code
var name = 'cao1'; var obj = {name: 'cao2'}; Function.prototype.call1_ = function (obj) { var arr = [] for (var i = 1, len = arguments.length; i < len; i++) { arr.push("arguments[" + i + "]") } obj.fn = this; eval("obj.fn(" + arr + ")"); Eval ("var a=1"); delete obj.fn; } function fn2(a, b, c) { console.log(a + b + c + this.name); }; fn2.call1_(obj, 1, 2, 3); Fn2.call1_ (obj, "my "," name ", "yes "); // Args.push (arguments[I]) = eval("obj.fn(my, name, is)")Copy the code

6. Development and use

6.1 Changing the This Pointer

6.2 Data Type Detection

function type(obj) { return Object.prototype.toString.call(obj)[1]; }; type([123]); //Array type('123'); //String type(123); //Number type(null); //Null type(undefined); //UndefinedCopy the code

6.2 Take the maximum value and the minimum value of the array

var arr = [11, 1, 0, 2, 3, 5]; var max1 = Math.max.call(null, ... arr); var max2 = Math.max.apply(null, arr); var min1 = Math.min.call(null, ... arr); var min2 = Math.min.apply(null, arr);Copy the code

6.3 Function Arguments Class array operations

var fn = function () { var arr = Array.prototype.slice.call(arguments); console.log(arr); //[1, 2, 3, 4]}; fn(1, 2, 3, 4);Copy the code