preface

Call /apply/bind (); call/apply/bind ();

  1. bind: Does not execute the function immediately and takes the form of a sequence of arguments
  2. call: Executes the function immediately, taking the form of a sequence of arguments
  3. apply: Executes the function immediately, passing an array of arguments

The basic idea

  1. bind

Using the Idea of a Cremation function, bind() returns a new function that is also a use case for closures.

  1. call

1. Call this. This is the function that calls the call method, let’s say fn1. 2. Change the this pointer of fn1 to the one you specify.

  1. apply

The apply and call methods have the same idea, except that they pass different types of arguments.

In the code

   let obj = {
      fn(x, y) {
        console.log(this, x, y)
      }
    }
Copy the code

Using self-executing functions to form closures protects methods from global effects.

~function anonymous(proto) {
      function bind(context) {
        context == null ? window : context // Consider special cases null and undefined
        let _this = this
        let args = [].slice.call(arguments.1) 
        // Use es5 to convert the class array to an array.
        / / can also write Array. Prototype. Slice. Call (1) the arguments,
        / / the console. The log (args) [10, 20]
        return function proxy() {
          _this.apply(context, args)
        }
      }
      function call(context, ... args) {
        /* execute this as fn1; /* execute this as fn1; 3. Consider special cases where context is not a reference type and you need to convert */ yourself
        context == null ? window : context
        const type = typeof context
        if(type ! = ='object'&& type ! = ='function'&& type ! = ='symble') {
          // Basic data type
          switch (type) {
            case ('number'): context = new Number(context); break;
            case ('string'): context = new String(context); break;
            case ('Boolean'): context = new Boolean(context); break;
          }
        }
        context.$fn = this
        constres = context.$fn(... args)return res
      }
      function apply(context, args) {
        context == null ? window : context
        const type = typeof context
        if(type ! = ='object'&& type ! = ='function'&& type ! = ='symble') {
          // Basic data type
          switch (type) {
            case ('number'): context = new Number(context); break;
            case ('string'): context = new String(context); break;
            case ('Boolean'): context = new Boolean(context); break;
          }
        }
        context.$fn = this
        constres = context.$fn(... args)/ /
        return res
      }
      proto.bind = bind
      proto.call = call
      proto.apply = apply
    }(Function.prototype)
Copy the code

Testing:

    setTimeout(obj.fn.bind(window.10.20), 1000)
    obj.fn.call('4'.10.20) // String {'4', $fn: ƒ} 10 20
    obj.fn.apply('4'[10.20]) // String {'4', $fn: ƒ} 10 20
Copy the code