Heim Web-Frontend js-Tutorial So implementieren Sie bind in Javascript

So implementieren Sie bind in Javascript

Jun 13, 2018 pm 03:30 PM
bind javascript

In diesem Artikel wird hauptsächlich der Prozess vom Erlernen von Bind bis zur Implementierung von Bind in Javascript vorgestellt. Interessierte Freunde können mitmachen und lernen.

Was ist bind?

Die Methode bind() erstellt eine neue Funktion und setzt beim Aufruf ihr Schlüsselwort this auf den bereitgestellten Wert of stellt beim Aufruf einer neuen Funktion eine bestimmte Folge von Argumenten vor jeder Lieferung bereit.

var result = fun.bind(thisArg[, arg1[, arg2[, ...]]]) 
result(newArg1, newArg2...)
Nach dem Login kopieren

Wenn Sie es nicht verstehen, machen Sie sich keine Sorgen, lesen Sie weiter.

Was genau macht bind?

Drei Punkte sind aus der obigen Einführung ersichtlich. Erstens gibt der Aufruf der Bind-Methode eine neue Funktion zurück (der Funktionskörper dieser neuen Funktion sollte mit fun identisch sein). Gleichzeitig werden in bind zwei Parameter übergeben. Der erste wird durch this angezeigt, das heißt, was auch immer übergeben wird, ist gleich dem, was es ist. Wie im folgenden Code gezeigt:

this.value = 2
var foo = {
  value: 1
}
var bar = function() {
 console.log(this.value)
}
var result = bar.bind(foo)
bar() // 2
result() // 1,即this === foo
Nach dem Login kopieren

Der zweite Parameter ist eine Sequenz, in die Sie beliebig viele Parameter übergeben können. Und es wird vor den neuen Funktionsparametern voreingestellt.

this.value = 2
var foo = {
  value: 1
};
var bar = function(name, age, school) {
 console.log(name) // 'An'
 console.log(age) // 22
 console.log(school) // '家里蹲大学'
}
var result = bar.bind(foo, 'An') //预置了部分参数'An'
result(22, '家里蹲大学') //这个参数会和预置的参数合并到一起放入bar中
Nach dem Login kopieren

Wir können sehen, dass result(22, 'Study at home in College') schließlich aufgerufen wurde, es bereits das 'An' enthielt, das beim Aufruf von bind übergeben wurde.

Ein Satz Zusammenfassung: Der Aufruf von bind gibt eine neue Funktion zurück. Dies zeigt in dieser Funktion auf den ersten Parameter von bind, und die darauf folgenden Parameter werden im Voraus an diese neue Funktion übergeben. Beim Aufruf der neuen Funktion werden die übergebenen Parameter nach den voreingestellten Parametern platziert und gemeinsam an die neue Funktion übergeben.

Implementieren Sie eine Bindung selbst

Um eine Bindung zu implementieren, müssen Sie die folgenden zwei Funktionen implementieren

Gib a zurück Funktion und binden Sie dies, übergeben Sie die voreingestellten Parameter

Die von bind zurückgegebene Funktion kann als Konstruktor verwendet werden. Daher sollte dies bei Verwendung als Konstruktor ungültig sein, aber die übergebenen Parameter sind immer noch gültig

1 Geben Sie eine Funktion zurück, binden Sie diese und übergeben Sie die voreingestellten Parameter

this.value = 2
var foo = {
  value: 1
};
var bar = function(name, age, school) {
  console.log(name) // 'An'
  console.log(age) // 22
  console.log(school) // '家里蹲大学'
  console.log(this.value) // 1
}
Function.prototype.bind = function(newThis) {
  var aArgs  = Array.prototype.slice.call(arguments, 1) //拿到除了newThis之外的预置参数序列
  var that = this
  return function() {
    return that.apply(newThis, aArgs.concat(Array.prototype.slice.call(arguments)))
    //绑定this同时将调用时传递的序列和预置序列进行合并
  }
}
var result = bar.bind(foo, 'An')
result(22, '家里蹲大学')
Nach dem Login kopieren

Es gibt Ein Detail hier: Array.prototype.slice.call(arguments, 1) In diesem Satz wissen wir, dass die Variable arguments die beim Aufruf der Funktion übergebenen Parameter abrufen kann, aber es ist kein Array, sondern hat ein Längenattribut . Warum kann es durch diesen Aufruf in ein reines Array umgewandelt werden? Dann müssen wir zur Analyse zum Quellcode von V8 zurückkehren. #Der Quellcode dieser Version ist eine frühe Version mit relativ wenig Inhalt.

function ArraySlice(start, end) {
 var len = ToUint32(this.length); 
 //需要传递this指向对象,那么call(arguments),
 //便可将this绑定到arguments,拿到其length属性。
 var start_i = TO_INTEGER(start);
 var end_i = len;
 if (end !== void 0) end_i = TO_INTEGER(end);
 if (start_i < 0) {
  start_i += len;
  if (start_i < 0) start_i = 0;
 } else {
  if (start_i > len) start_i = len;
 }
 if (end_i < 0) {
  end_i += len;
  if (end_i < 0) end_i = 0;
 } else {
  if (end_i > len) end_i = len;
 }
 var result = [];
 if (end_i < start_i)
  return result;
 if (IS_ARRAY(this))
  SmartSlice(this, start_i, end_i - start_i, len, result);
 else 
  SimpleSlice(this, start_i, end_i - start_i, len, result);
 result.length = end_i - start_i;
 return result;
};
Nach dem Login kopieren

Sie können dem Quellcode entnehmen, dass Sie nach der Zuweisung des Längenattributs unter den Argumenten zum Slice-Through-Aufruf das endgültige Array über start_i und end_i erhalten können, sodass es sich um ein reines Array handelt, wenn dies nicht erforderlich ist an Slice übergeben werden. Sie können auch eine Array-Variable erhalten.

2. Die von bind zurückgegebene Funktion kann als Konstruktor verwendet werden.

Bei Verwendung als Konstruktor sollte diese auf die von new erzeugte Instanz verweisen und es sollte auch ein Prototypattribut vorhanden sein , was auf den Prototyp der Instanz verweist.

this.value = 2
var foo = {
 value: 1
};
var bar = function(name, age, school) {
 ...
 console.log(&#39;this.value&#39;, this.value)
}
Function.prototype.bind = function(newThis) {
 var aArgs  = Array.prototype.slice.call(arguments, 1)
 var that = this //that始终指向bar
 var NoFunc = function() {}
 var resultFunc = function() {
  return that.apply(this instanceof that ? this : newThis, aArgs.concat(Array.prototype.slice.call(arguments)))
 } 
 NoFunc.prototype = that.prototype //that指向bar
 resultFunc.prototype = new NoFunc()
 return resultFunc
}
var result = bar.bind(foo, &#39;An&#39;)
result.prototype.name = &#39;Lsc&#39; // 有prototype属性
var person = new result(22, &#39;家里蹲大学&#39;)
console.log(&#39;person&#39;, person.name) //&#39;Lsc&#39;
Nach dem Login kopieren

Der obige Simulationscode erledigt zwei wichtige Dinge.

1. Simulieren Sie ein Prototypattribut für die zurückgegebene Funktion. , weil die auf dem Prototyp definierten Eigenschaften und Methoden über die Instanz vom Konstruktor abgefragt werden können new

var NoFunc = function() {}
...
NoFunc.prototype = that.prototype //that指向bar
resultFunc.prototype = new NoFunc()
return resultFunc
Nach dem Login kopieren

Wie aus dem obigen Code ersichtlich ist, zeigt dieser immer auf bar. Gleichzeitig hat die zurückgegebene Funktion that.prototype geerbt, also bar.prototype. Warum nicht einfach das Prototypattribut resultFunc.prototype der zurückgegebenen Funktion gleich bar(that).prototype machen? Dies liegt daran, dass jede neue Instanz auf die Prototypenkette zugreifen kann. Bei direkter Zuweisung kann das neue Objekt die Prototypenkette der Balkenfunktion direkt ändern, was eine Verschmutzung der Prototypenkette darstellt. Daher verwenden wir Vererbung (weisen Sie die Prototypenkette des Konstruktors der Instanz des übergeordneten Konstruktors zu), um die Prototypenkette des neuen Objekts von bar zu trennen.

2. Bestimmen Sie, ob dies für die normale Bindung oder für den Konstruktor verwendet wird, wenn er aktuell aufgerufen wird, um den Punkt davon zu ändern.

Wie können wir feststellen, wohin dies gerade zeigt? Vom ersten Punkt an wissen wir bereits, dass die neue Funktion, die von der Bindungsmethode zurückgegeben wird, bereits über eine Prototypenkette verfügt Darauf zeigen, um es zu simulieren. So ermitteln Sie die aktuell aufgerufene Haltung. Die Antwort ist Instanz von. Der Operator

instanceof wird verwendet, um zu testen, ob ein Objekt in seiner Prototypenkette über die Prototypeigenschaft eines Konstruktors verfügt.

// 定义构造函数
function C(){} 
function D(){} 
var o = new C();
// true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof C; 
// false,因为 D.prototype不在o的原型链上
o instanceof D;
Nach dem Login kopieren

Wie aus dem Obigen ersichtlich ist, kann Instanz von anhand dieser Funktion feststellen, ob ein Objekt neu ist. Wenn es neu ist, sollte die Prototypenkette dieses Objekts der Prototyp der Funktion sein.

Schauen wir uns also die Struktur der zurückgegebenen Schlüsselfunktion an:

var resultFunc = function() {
  return that.apply(this instanceof that ? 
    this : 
    newThis, 
    aArgs.concat(Array.prototype.slice.call(arguments)))
 }
Nach dem Login kopieren

Dabei müssen wir zunächst erkennen, dass dies in dieser Instanz die neue Funktion ist, die nach dem Aufruf der Bindefunktion zurückgegeben wird. Dies kann also in einer normalen Scope-Umgebung ausgeführt werden, und es kann auch neu sein, die Richtung zu ändern. Wenn man das noch einmal betrachtet, zeigt das immer auf bar und seine Prototypenkette that.prototype existiert immer. Wenn diese neue Funktion nun eine neue Operation ausführen muss, dann zeigt dies auf die neue Funktion, dann ist diese Instanz davon === wahr, also übergeben Sie dies in apply als Zeiger, der auf die neue Funktion zeigt. Wenn es sich um einen normalen Aufruf handelt, wird dieser nicht von new erstellt, d. h. die neue Funktion wird nicht als Konstruktor verwendet, und diese Instanz davon === false ist offensichtlich. Diesmal handelt es sich um einen normalen Bind-Aufruf. Verwenden Sie einfach den ersten Parameter des Aufrufs als Zeiger darauf.

完整代码(MDN下的实现)

if (!Function.prototype.bind) {
 Function.prototype.bind = function(oThis) {
  if (typeof this !== &#39;function&#39;) {
   // closest thing possible to the ECMAScript 5
   // internal IsCallable function
   throw new TypeError(&#39;Function.prototype.bind - what is trying to be bound is not callable&#39;);
  }

  var aArgs  = Array.prototype.slice.call(arguments, 1),
    fToBind = this,
    fNOP  = function() {},
    fBound = function() {
     return fToBind.apply(this instanceof fNOP
         ? this
         : oThis,
         aArgs.concat(Array.prototype.slice.call(arguments)));
    };

  if (this.prototype) {
   // Function.prototype doesn&#39;t have a prototype property
   fNOP.prototype = this.prototype; 
  }
  fBound.prototype = new fNOP();
  return fBound;
 };
}
Nach dem Login kopieren

可以看到,其首先做了当前是否支持bind的判定,不支持再实行兼容。同时判断调用这个方法的对象是否是个函数,如果不是则报错。

同时这个模拟的方法也有一些缺陷,可关注MDN上的Polyfill部分

小结

模拟bind实现最大的一个缺陷是,模拟出来的函数中会一直存在prototype属性,但是原生的bind作为构造函数是没有prototype的,这点打印一下即可知。不过这样子new出来的实例没有原型链,那么它的意义是什么呢。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

MVVM框架如何解析双向绑定

JS运动特效

JS中链式运动(详细教程)

Das obige ist der detaillierte Inhalt vonSo implementieren Sie bind in Javascript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript Dec 17, 2023 pm 02:54 PM

So implementieren Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem. Einführung: Mit der kontinuierlichen Weiterentwicklung der Technologie ist die Spracherkennungstechnologie zu einem wichtigen Bestandteil des Bereichs der künstlichen Intelligenz geworden. Das auf WebSocket und JavaScript basierende Online-Spracherkennungssystem zeichnet sich durch geringe Latenz, Echtzeit und plattformübergreifende Eigenschaften aus und hat sich zu einer weit verbreiteten Lösung entwickelt. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem implementieren.

WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen Dec 17, 2023 pm 05:30 PM

WebSocket und JavaScript: Schlüsseltechnologien zur Realisierung von Echtzeit-Überwachungssystemen Einführung: Mit der rasanten Entwicklung der Internet-Technologie wurden Echtzeit-Überwachungssysteme in verschiedenen Bereichen weit verbreitet eingesetzt. Eine der Schlüsseltechnologien zur Erzielung einer Echtzeitüberwachung ist die Kombination von WebSocket und JavaScript. In diesem Artikel wird die Anwendung von WebSocket und JavaScript in Echtzeitüberwachungssystemen vorgestellt, Codebeispiele gegeben und deren Implementierungsprinzipien ausführlich erläutert. 1. WebSocket-Technologie

So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript Dec 17, 2023 am 09:39 AM

So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript. Im heutigen digitalen Zeitalter müssen immer mehr Unternehmen und Dienste Online-Reservierungsfunktionen bereitstellen. Es ist von entscheidender Bedeutung, ein effizientes Online-Reservierungssystem in Echtzeit zu implementieren. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Reservierungssystem implementieren, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist WebSocket? WebSocket ist eine Vollduplex-Methode für eine einzelne TCP-Verbindung.

Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Dec 17, 2023 pm 12:09 PM

Einführung in die Verwendung von JavaScript und WebSocket zur Implementierung eines Online-Bestellsystems in Echtzeit: Mit der Popularität des Internets und dem Fortschritt der Technologie haben immer mehr Restaurants damit begonnen, Online-Bestelldienste anzubieten. Um ein Echtzeit-Online-Bestellsystem zu implementieren, können wir JavaScript und WebSocket-Technologie verwenden. WebSocket ist ein Vollduplex-Kommunikationsprotokoll, das auf dem TCP-Protokoll basiert und eine bidirektionale Kommunikation zwischen Client und Server in Echtzeit realisieren kann. Im Echtzeit-Online-Bestellsystem, wenn der Benutzer Gerichte auswählt und eine Bestellung aufgibt

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Dec 17, 2023 pm 05:13 PM

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Einführung: Heutzutage ist die Genauigkeit von Wettervorhersagen für das tägliche Leben und die Entscheidungsfindung von großer Bedeutung. Mit der Weiterentwicklung der Technologie können wir genauere und zuverlässigere Wettervorhersagen liefern, indem wir Wetterdaten in Echtzeit erhalten. In diesem Artikel erfahren Sie, wie Sie mit JavaScript und WebSocket-Technologie ein effizientes Echtzeit-Wettervorhersagesystem aufbauen. In diesem Artikel wird der Implementierungsprozess anhand spezifischer Codebeispiele demonstriert. Wir

Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Jan 05, 2024 pm 06:08 PM

JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

So verwenden Sie insertBefore in Javascript So verwenden Sie insertBefore in Javascript Nov 24, 2023 am 11:56 AM

Verwendung: In JavaScript wird die Methode insertBefore() verwendet, um einen neuen Knoten in den DOM-Baum einzufügen. Diese Methode erfordert zwei Parameter: den neuen Knoten, der eingefügt werden soll, und den Referenzknoten (d. h. den Knoten, an dem der neue Knoten eingefügt wird).

So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript Jan 05, 2024 pm 01:37 PM

Einführung in die Methode zum Abrufen des HTTP-Statuscodes in JavaScript: Bei der Front-End-Entwicklung müssen wir uns häufig mit der Interaktion mit der Back-End-Schnittstelle befassen, und der HTTP-Statuscode ist ein sehr wichtiger Teil davon. Das Verstehen und Abrufen von HTTP-Statuscodes hilft uns, die von der Schnittstelle zurückgegebenen Daten besser zu verarbeiten. In diesem Artikel wird erläutert, wie Sie mithilfe von JavaScript HTTP-Statuscodes erhalten, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist ein HTTP-Statuscode? HTTP-Statuscode bedeutet, dass der Dienst den Dienst anfordert, wenn er eine Anfrage an den Server initiiert

See all articles