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
- 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