define

The same

  • All three of these are for modifying this.
  • The first argument accepted is the this point to be bound.

The difference between

  • The second argument to apply is an array of arguments, while the second and subsequent arguments to call and bind are passed in order as function arguments.
  • Call and apply are immediately called, while bind returns a new function that this points to, leaving the old function unaffected.

implementation

Handwritten call function

Question:

  1. Where is the function defined?
    • Call can be called by any function, so is in function prototype
  2. How to display binding this?
    • You can bind a function to an object, so when called through obj.fn, the function’s this points to obj
  3. How to transfer the cords
    • Arguments to get arguments other than index 0

code

Function. The prototype. MyCall = Function (context) {/ / exception handling is done first, determine whether Function if (typeof this! == 'function '{// throw new TypeError('Error')} In terms of the demo below is object lisi const CTX = context | | window; Ctx.fn = this; // This is the method called. Array.from can also be const arg = [...arguments].slice(1); Const res = arguments.length > 1 const res = arguments.length > 1 const res = arguments.length > 1 ctx.fn(... arg) : ctx.fn(); // Delete this method to keep the incoming object pure, otherwise it will pollute the incoming object. Return res; }Copy the code

demo

const zhangsan = {
    name: 'zhangsan',
    getName: function() {
        console.log(this.name)
    }
}

const lisi = {
    name: 'lisi'
}

console.log(zhangsan.getName.myCall(lisi))   //lisi
Copy the code

Handwritten Apply function

Question:

  1. Where is the function defined?
    • Refer to the call function
  2. How to display binding this?
    • Refer to the call function
  3. How to transfer the cords
    • Apply accepts an array of parameters

code

Function.prototype.myApply = function(context) { if(typeof ! == 'function') { throw new TypeError('Error') } const ctx = context || window; ctx.fn = this; // Because apply takes two arguments, context and an array of arguments const arg = argument[1]; const res = arg ? ctx.fn(... arg) : ctx.fn(); delete ctx.fn; return res; }Copy the code

demo

const zhangsan = {
    name: 'zhangsan',
    getName: function() {
        console.log(this.name)
    }
}

const lisi = {
    name: 'lisi'
}

console.log(zhangsan.getName.myApply(lisi))   //lisi
Copy the code

Handwritten bind

Question:

  1. Where is the function defined?
    • Call can be called by any function, so is in function prototype
  2. How to display binding this?
    • You can bind a function to an object, so when called through obj.fn, the function’s this points to obj
  3. How to transfer the cords
    • The bind function returns a bind function, and the final call requires passing in function arguments and the arguments to the bind function

code

Function.prototype.myBind = function(context) { if(typeOf this ! == 'function) { throw new TypeError('error') } const ctx = context || window; const arg = [...arguments].slice(1); const _this = this; If (this instanceOf F) {return New _this(... ars, ... arguments) } return _this.applay(ctx, arg.contact(... arguments)) } }Copy the code
  • Bind returns a function, and there are two ways to call a function, either directly or through new, so let’s talk about calling it directly
  • For direct calls, we chose apply, but for parameters we need to be aware of the following: Since bind can implement code like f.bind(obj,1)(2), we need to concatenate the two arguments, resulting in the implementation of args.concat(… arguments)
  • In the case of new, this will not be changed in any way, so in that case we need to ignore this, which should point to the constructed instance, not the first argument in the bind bind

demo

function getName(name) { this.name = name; } const animal = {}; let person = getName.myBind(animal); The person (' people '); console.log(`animal.name`, animal.name); // const zhangsan = new person('zhangsan'); console.log(`zhangsan`, zhangsan); //getName {name: "zhangsan"} console.log(`animal.name`, animal.name); / /Copy the code

Knowledge points involved:

  • Error type definition, etc
  • The arguments,
  • TypeOf and instanceOf

reference

  • Blog.csdn.net/qq_37288477…
  • Segmentfault.com/a/119000001…