1. Call, apply, bind

  • Common: Both can change the “this” direction

  • Difference:

    • call()apply() Will call the functionAnd change the inside of the functionthisPointing to.
    • call()apply()The parameters passed are different,call()Pass parameters usingcommas.apply()useThe array passed
    • bind() No function callsYou can change the inside of the functionthisPoint to the
  • Application scenarios

    1. call()oftenDo the inheritance
    2. apply()oftenIt has to do with arraysFor example, using mathematical objects to achieve the maximum and minimum values of arrays
    3. bind()Not calling a functionBut still want to changethisPointing, like changing the inside of the timerthisPoint to the
call() apply() bind()
The same Change the functionthisPoint to the Change the functionthisPoint to the Change the functionthisPoint to the
Whether to call a function is is no
Passing parameters The comma.separated An array[] The comma.separated
Application scenarios inheritance With arrays Don’t want to call a function

2. To realize the call

  • Take the first parameter ascallFunction internal temporary objectobj
  • toobjAn attributefn, becomes the actual execution function, and willthisThe keyword points to this property
  • Execute this function and get the return value
  • Delete function attributes
  • Returns the result of the function’s execution
/ / implementation call
Function.prototype.myCall = function (obj, ... args) {
    // Determine the context
    const newObj = obj ? Object(obj) : global;
    // Set the function as an object property
    newObj.fn = this;
    // Execute this function and get the return value
    constres = newObj.fn(... args);// Remove the function attribute
    delete newObj.fn;
    / / the return value
    return res;
};
Copy the code

3. Realize the apply

The second parameter of apply is passed as an array, so the basic steps are the same as those of call, except that the function is executed to check whether the second parameter is passed. If so, pass it in and execute it; If not, execute it directly.

/ / the apply
Function.prototype.myApply = function (obj, arr) {
    // Determine the context
    const newObj = obj ? Object(obj) : global;
    // Set the function as an object property
    newObj.fn = this;
    // Execute this function and get the return value
    let res;
    if(arr) { res = newObj.fn(... arr); }else {
        res = newObj.fn();
    }
    // Remove the function attribute
    delete newObj.fn;
    / / the return value
    return res;
};
Copy the code

4. Realize the bind

The bind / / implementation
Function.prototype.MyBind = function (context) {
    // Call the method itself
    const self = this;
    // Class array -> true array
    const args = Array.prototype.slice.call(arguments.1);
    // transfer function
    const temp = function () {};
    const fn = function () {
        // Group the arguments number from the execution of the new function and merge it with the arguments from the binding
        const newArgs = Array.prototype.slice.call(arguments);
        // This should be an instance of fn if called by new
        return self.apply(this instanceof fn ? this : context || global, args.concat(newArgs));
    };
    // Transfer the prototype chain
    temp.prototype = self.prototype;
    fn.prototype = new temp();
    return fn;
};
Copy the code

Source code: “JavaScript hand rip code”