También hable sobre cómo implementar vincular, aplicar, llamar

También hable sobre cómo implementar vincular, aplicar, llamar

Sabemos que el enlace, la aplicación y la llamada de JavaScript son tres métodos muy importantes. bind puede devolver envoltorios de funciones con esto fijo y parámetros fijos; aplicar y llamar puede modificar el señalamiento de la función miembro esto. La implementación de vincular, aplicar y llamar es un problema de alta frecuencia en las entrevistas frontales, y también nos permite comprender y dominar mejor el conocimiento relevante de las funciones de JavaScript. Este artículo presentará cómo implementar vincular, aplicar y llamar usted mismo.

Prólogo

Este artículo primero ofrece la siguiente definición de clase y definición de instancia.

// 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')

Implementar enlace

Es posible que desee revisar el uso de bind primero:

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

Visible:

  • bind devuelve una copia de la función (función envuelta), arregló esto y los parámetros reales. esto no apunta a la persona que llama
  • bind es un método en el prototipo de la función

Conociendo estos dos puntos, no es difícil escribir una implementación:

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

Implementar llamada

Utilizamos call en el proceso de implementación de bind. Entonces, ¿cómo implementar una llamada? Es posible que desee revisar el uso de la llamada:

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

Visible:

  • bind modifica esto de la función actual para que no apunte a la persona que llama
  • Se pasan argumentos en ... descanso

Conociendo estos dos puntos, no es difícil escribir una implementación:

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

Implementar aplicar

Las funciones de apply y call son las mismas, y los métodos de uso son básicamente similares. La única diferencia es:

  • Los parámetros se pasan como una matriz

Por lo tanto, puedes escribir para lograr:

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

Triángulo estable

De lo anterior, podemos ver que apply y call pueden lograr bind, entonces, ¿cómo usar bind para implementar apply y call, a fin de crear esta relación de triángulo de hierro?

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

Simple! ¡Simplemente ejecute esta copia de función inmediatamente!

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

Supongo que te gusta

Origin www.cnblogs.com/zxuuu/p/12735316.html
Recomendado
Clasificación