Sprechen Sie auch darüber, wie Sie Binden, Anwenden und Aufrufen implementieren

Sprechen Sie auch darüber, wie Sie Binden, Anwenden und Aufrufen implementieren

Wir wissen, dass das Binden, Anwenden und Aufrufen von JavaScript drei sehr wichtige Methoden sind. bind kann Funktions-Wrapper mit festen this- und festen Parametern zurückgeben, apply und call können das Zeigen der Member-Funktion this ändern. Das Implementieren von Binden, Anwenden und Aufrufen ist ein häufiges Problem in Front-End-Interviews und ermöglicht es uns, das relevante Wissen über JavaScript-Funktionen besser zu verstehen und zu beherrschen. In diesem Artikel wird beschrieben, wie Sie das Binden, Anwenden und Aufrufen selbst implementieren.

Vorwort

Dieser Artikel enthält zunächst die folgende Klassendefinition und Instanzdefinition.

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

Binden implementieren

Möglicherweise möchten Sie zuerst die Verwendung von bind überprüfen:

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

Sichtbar:

  • bind gibt eine Kopie der Funktion (umschlossene Funktion) zurück, korrigiert diese und die tatsächlichen Parameter. Dies zeigt nicht auf den Anrufer
  • bind ist eine Methode für den Funktionsprototyp

Wenn man diese beiden Punkte kennt, ist es nicht schwierig, eine Implementierung zu schreiben:

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

Aufruf implementieren

Wir haben call bei der Implementierung von bind verwendet. Wie kann man einen Anruf implementieren? Möglicherweise möchten Sie die Verwendung des Anrufs überprüfen:

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

Sichtbar:

  • bind Ändern Sie dies für die aktuelle Funktion so, dass sie nicht auf den Aufrufer zeigt
  • Argumente werden in ... rest übergeben

Wenn man diese beiden Punkte kennt, ist es nicht schwierig, eine Implementierung zu schreiben:

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

Implementieren anwenden

Die Funktionen von apply und call sind gleich und die Verwendungsmethoden sind grundsätzlich ähnlich.

  • Parameter werden als Array übergeben

Daher können Sie schreiben, um Folgendes zu erreichen:

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

Stabiles Dreieck

Aus dem Obigen können wir ersehen, dass Apply und Call Bind erreichen können. Wie kann man also Bind verwenden, um Apply und Call zu implementieren, um diese eiserne Dreiecksbeziehung zu erstellen?

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

Einfach! Führen Sie diese Funktionskopie einfach sofort aus!

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

Ich denke du magst

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