Also talk about how to implement bind, apply, call

Also talk about how to implement bind, apply, call

We know that JavaScript's bind, apply, and call are three very important methods. bind can return function wrappers with fixed this and fixed parameters; apply and call can modify the pointing of member function this. Implementing bind, apply, and call is a high-frequency problem in front-end interviews, and also allows us to better understand and master the relevant knowledge of JavaScript functions. This article will introduce how to implement bind, apply and call by yourself.

Recap

This article first gives the following class definition and instance definition.

// Person类,每个人有姓名,有打印姓名的方法
function Person(_name) {
  this.name = _name
  this.sayMyName = function (postfix) {
    console.log(this.name + postfix)
  }
}
// 两个实例
let alex = new Person('Alex')
let bob = new Person('Bob')

Implement bind

May wish to review the use of bind first:

let sayBobName = alex.sayMyName.bind(bob, '?')
sayBobName() // Bob?

visible:

  • bind returns a copy of the function (wrapped function), fixed this and actual parameters. this does not point to the caller
  • bind is a method on the function prototype

Knowing these two points, it is not difficult to write an implementation:

function MyBind(context, ...args) {
  let that = this // this是调用者,也就是被包装的函数(alex.sayMyName)
  return function () { // 返回一个包装过的函数
    return that.call(context, ...args) // 其返回值是以context为this的执行结果
  }
}
Function.prototype.bind = MyBind

Implement call

We used call in the process of implementing bind. So how to implement a call? May wish to review the use of call:

alex.sayMyName.call(bob, '!') // Bob!

visible:

  • bind modify this of the current function so that it does not point to the caller
  • Arguments are passed in ... rest

Knowing these two points, it is not difficult to write an implementation:

function MyCall(context, ...args) {
  context._fn = this // this是调用者,也就是当前函数。此步给context绑上该函数
  // 有个细节问题是,可能需要备份原先的context._fn,避免意外覆盖
  let ret = context._fn(..args) // 模仿context自己调用_fn
  delete context._fn // 移除绑的函数
  return ret
}
Function.prototype.call = MyCall

Implement apply

The functions of apply and call are the same, and the methods of use are basically similar. The only difference is:

  • Parameters are passed in as an array

Therefore, you can write to achieve:

function MyApply(context, args) {
  return MyCall(context, ...args)
}
Function.prototype.apply = MyApply

Stable triangle

From the above we can see that apply and call can achieve bind, so how to use bind to implement apply and call, so as to create this iron triangle relationship?

    bind
  /      \      两两都可互相实现的三角形!
call -- apply

simple! Just execute this function copy immediately!

function AnotherMyCall(context, ...args) {
  return (this.bind(context, ...args))()
}

Guess you like

Origin www.cnblogs.com/zxuuu/p/12735316.html