Heim >Web-Frontend >js-Tutorial >Pragmatische Verwendungen von Affenpaticken in JavaScript
Kernpunkte
Dieser Artikel wurde von Moritz Kröger und Tom Greco überprüft. Vielen Dank an alle Peer -Rezensenten bei SitePoint für die Erhöhung der Inhalte von SitePoint -Inhalten!
Haben Sie jemals Code von Drittanbietern verwendet, der gut funktioniert, bis auf eine kleine Frage, die Sie verrückt macht? Warum hat der Schöpfer vergessen, diese nervigen Konsolenprotokolle zu löschen? Wäre das nicht schön, wenn dieser API -Anruf noch etwas tun könnte? Wenn ja, dann wissen Sie, dass der Wartungspunkt Ihre Änderungen schwierig (oder unmöglich) sein kann. Aber was ist mit dem Code selbst? Was ist, wenn Sie keinen Quellcode haben und sie nicht selbst hosten möchten? Willkommen in der World Journey of JavaScript Monkey Patch!
In diesem Artikel werden wir erfahren, was ein Affenpatch ist, und einige verschiedene Beispiele durchführen, um die Funktionalität eines Widgets von Drittanbietern so zu ändern, dass er unseren Anforderungen entspricht.
Was ist ein Affenpatch?
Monkey Patch (MP) ist eine Technik, mit der das Standardverhalten von Codesegmenten überschrieben, erweitert und sogar unterdrückt wird, ohne den ursprünglichen Quellcode zu ändern. Dies erfolgt durch das Ersetzen des ursprünglichen Verhaltens durch die fix -Version.
In diesem Artikel wird das vorhandene Feedback-Box-Widget verwendet, das ein einfaches, wischbares Popup-Fenster (im Bild unten gezeigt) mit dem Feedback-Formular anzeigt.
Der Quellcode wurde so geändert, dass Anwendungsfälle für die Verwendung als MP -Ziele einbezogen werden. Das Ziel bezieht sich auf die spezifischen Funktionen, Funktionen oder die Verwendung von Mindestniveau, die wir patchen. Eine weitere Änderung, die ich vorgenommen habe, bestand darin, den Ausdruck der Anruffunktion (IIFE) um den Code zu entfernen. Dies wird getan, um sich auf die MP -Technologie zu konzentrieren.
Sie finden das gesamte Beispiel in Plunker, einschließlich des in diesem Artikel diskutierten Affen Patch.
Ist Monkey Patch keine schlechte Praxis?
Bevor wir anfangen, machen wir klar: Ja, MP wird als schlechte Praxis angesehen-evil eval , imperative Programmierung, variable Datenstrukturen, Zwei-Wege-Bindung, also wird warten.
Wenn Sie beide davon verwenden, gibt es eine ziemlich große Gruppe von Menschen, die Ihnen sagen, dass Sie etwas falsch machen und dass dies oder das geändert werden sollte, um bessere Bedingungen zu erfüllen. Wie immer stehen jedoch verschiedene Tools und Technologien zur Verfügung, und ihre Anwendbarkeit variiert in bestimmten Szenarien. Manchmal kann etwas, das extrem, verrückt oder einfach schlecht aussieht, in einer bestimmten Situation ein letzter Ausweg. Da einige Praktiken als schlecht angesehen werden, können Sie nicht einmal viele Artikel finden, um zu beschreiben, wie man das Falsche richtig macht. Die hier beschriebene Situation kann unnatürlich sein, drücken sie mit gefälschten Widgets auf das Extrem, um Ihre Wahl zu zeigen. Dann müssen Sie als Leser entscheiden, ob Ihnen das gefällt, was Sie sehen. Wenn Sie diesen Artikel gelesen haben, haben Sie jedoch ein besseres Verständnis, um sich gegen MP zu erheben.
Ziel des Monkey Patch
Bevor wir uns tiefer in diese Technologien eintauchen, schauen wir uns zunächst an, was wir erreichen wollen. Das modifizierte Widget hat einen Code -Geruch, und wir möchten diese Probleme lösen.
hartcodierte Hintergrundfarbe
Wie Sie sehen, wird die Hintergrund-Color-Eigenschaft über die JQuery-Methode CSS festgelegt. Dies ist ein Problem, da wir es durch Stylesheet -Regeln angeben möchten.
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) { if(isError) { obj.css("background-color", "darkgrey"); } else { obj.css("background-color", ""); } }</code>
Nevil Console Log
AD -Server blockieren
<code class="language-javascript">FeedbackBox.prototype.init = function() { // 我们想要跳过的广告服务器调用 $.ajax('vendor/service.json', { method: 'GET' }).then(function(data) { console.log("FeedbackBox: AdServer contacted"); }); ... </code>
Hinweis: Der Demo -Code simuliert die ausgehenden AJAX -Anfragen für JSON -Dateien in Plunker, aber ich hoffe, Sie verstehen dies.
Abdeckungsmethode
Eines der Schlüsselkonzepte von MP ist es, vorhandene Funktionen zu erhalten und diese vor oder nach dem Aufrufen des ursprünglichen Code mit benutzerdefiniertem Verhalten zu verbessern. Das Aufrufen der ursprünglichen Implementierung ist jedoch nicht immer notwendig, da Sie sie manchmal nur durch benutzerdefinierte Aktionen ersetzen möchten. Dieser Ansatz eignet sich hervorragend, um uns zu helfen, das Problem der fleißigen Hintergrundfarbe zu lösen.Der Ort, an dem der MP angewendet wird, muss geladen und mit der ursprünglichen Implementierung versorgt werden. Im Allgemeinen sollten Sie sich bemühen, die Änderungen so nahe wie möglich an Ihr Ziel zu bringen, aber denken Sie daran, dass sich die Umsetzung des Ziels im Laufe der Zeit ändern kann. In unserem Beispiel werden Initialisierung und MP zur Datei main.js.
Wenn wir uns die Widget -Implementierung ansehen, können wir feststellen, dass es ein Feedback -Objekt als Stammwurzel des Widgets gibt. Später wird die ToggleError -Funktion in ihrem Prototyp implementiert.
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) { if(isError) { obj.css("background-color", "darkgrey"); } else { obj.css("background-color", ""); } }</code>
Da JavaScript eine dynamische Sprache ist, deren Objekte zur Laufzeit geändert werden können, werden wir lediglich ToggleError durch unsere benutzerdefinierte Methode ersetzen. Das einzige, was zu beachten ist, ist, die Signatur (Name und Übergabeparameter) gleich zu halten.
<code class="language-javascript">FeedbackBox.prototype.init = function() { // 我们想要跳过的广告服务器调用 $.ajax('vendor/service.json', { method: 'GET' }).then(function(data) { console.log("FeedbackBox: AdServer contacted"); }); ... </code>
Die neue Implementierung fügt dem angegebenen Element jetzt einfach eine Fehlerklasse hinzu, sodass wir die Hintergrundfarbe über CSS festlegen können.
Verbesserungsmethode
Im vorherigen Beispiel haben wir gesehen, wie die ursprüngliche Implementierung überschreibt, indem wir unsere eigenen Methoden bereitstellen. Auf der anderen Seite sollten die Verarbeitungskonsolenprotokolle nur bestimmte Anrufe herausfiltern und sie unterdrücken. Der Schlüssel zum Erfolg liegt darin, den Code zu untersuchen, den Sie einbetten, und versuchen, seinen Workflow zu verstehen. In der Regel erfolgt dies, indem die Entwicklerkonsole im Browser Ihrer Wahl gestartet und durch die geladenen Ressourcen, Hinzufügen von Haltepunkten und Debuggen der Objektcode -Abschnitte, um ihre Funktionalität zu verstehen. Dieses Mal müssen Sie jedoch nur die Implementierung im Plunker -Beispiel namens Vendor/jQuery.feedbackbox.js in einer anderen Registerkarte öffnen.
Wenn wir uns die Debug -Nachrichten ansehen, können wir sehen, dass jeder von ihnen mit Feedbackbox: beginnt. Eine einfache Möglichkeit, das zu erreichen, was wir wollen, besteht darin, den ursprünglichen Anruf abzufangen, den zu schriftlichen Text zu überprüfen und die ursprüngliche Methode nur dann aufzurufen, wenn er keine Debug -Eingabeaufforderung enthält.
, um dies zu tun, speichern wir zuerst die ursprüngliche Konsole.log in einer Variablen für die spätere Verwendung. Andererseits überschreiben wir die ursprüngliche Implementierung mit unserer benutzerdefinierten Implementierung, die zuerst überprüft, ob der angegebene Eigenschaftstext ein Zeichenfolge -Typ ist. Wenn ja, überprüft, ob er die Substring -Feedbackbox enthält: In diesem Fall werden wir nichts tun, andernfalls werden wir den ursprünglichen Konsolencode ausführen, indem wir seine Anwendungsmethode aufrufen.
Beachten Sie, dass diese Methode den Kontext als erster Parameter nimmt, was bedeutet, dass die Methode dieses Objekt sowie eine magische Argumentvariable aufgerufen werden sollte. Letzteres ist ein Array aller Parameter, die ursprünglich an den ursprünglichen Aufruf der Konsole übergeben wurden.
<code class="language-javascript">function FeedbackBox(elem, options) { this.options = options; this.element = elem; this.isOpen = false; } FeedbackBox.prototype.toggleError = function(obj, isError) { ... }</code>
Hinweis: Möglicherweise fragen Sie sich, warum wir das Textattribut nicht einfach weitergeleitet haben. Nun, Console.log kann tatsächlich mit unendlichen Parametern aufgerufen werden, die schließlich mit einem einzelnen Textausgang verbunden werden. Anstatt all diese Parameter zu definieren (was für unendliche Möglichkeiten sehr schwierig sein kann), leiten wir einfach alle eingehenden Inhalte weiter.
Abfangen ajax ruft
abLast but not least sehen wir uns an, wie das AD -Serverproblem löst. Schauen wir uns die Init -Funktion des Widgets noch einmal an:
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) { if(isError) { obj.css("background-color", "darkgrey"); } else { obj.css("background-color", ""); } }</code>
Die erste Idee könnte darin bestehen, einen Browser zu öffnen und nach dem Überschreiben des Jquery -Plugins zu suchen. Abhängig davon, wie gut Ihre Suchfähigkeiten sind, finden Sie möglicherweise die richtige Antwort. Aber lass uns anhalten und darüber nachdenken, was hier los ist. Egal was JQuery mit seiner Ajax -Methode macht, es erstellt irgendwann eine native XMLHTTPrequest.
Lassen Sie uns sehen, wie es hinter den Kulissen funktioniert. Das einfachste Beispiel für MDN zeigt uns Folgendes:
<code class="language-javascript">FeedbackBox.prototype.init = function() { // 我们想要跳过的广告服务器调用 $.ajax('vendor/service.json', { method: 'GET' }).then(function(data) { console.log("FeedbackBox: AdServer contacted"); }); ... </code>
Wir sehen eine neue XMLHTTPrequest -Instanz. Es hat eine OnreadyStatEchange -Methode, die uns eigentlich nicht interessiert, und dann die offenen und sendenden Methoden. Sehr gut. Unsere Idee ist es also, die Send -Methode zu patchen und sie zu sagen, dass sie keine Anrufe an eine bestimmte URL ausführen soll.
<code class="language-javascript">function FeedbackBox(elem, options) { this.options = options; this.element = elem; this.isOpen = false; } FeedbackBox.prototype.toggleError = function(obj, isError) { ... }</code>
OK, es stellt sich heraus, dass Sie die Ziel -URL nicht aus dem Objekt selbst erhalten können. Hoppla. Was sollen wir dann tun? Wir setzen es auf das Objekt. Auf der Suche nach der ersten Chance, die URL zu erhalten, können wir sehen, dass die offene Methode sie als zweite Parameter akzeptiert. Beginnen wir mit der MP Open -Methode, um die URL im Objekt selbst verfügbar zu machen.
Wie zuvor speichern wir die ursprüngliche offene Methode in einer Variablen für die spätere Verwendung. Anschließend überschreiben wir die ursprüngliche Implementierung mit einer benutzerdefinierten Implementierung. Da wir JavaScript (eine dynamische Sprache) verwenden können, können wir jederzeit eine neue Eigenschaft erstellen und sie nennen, die auf den Wert des übergebenen Parameters festgelegt wird.
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) { if(isError) { obj.addClass("error"); } else { obj.removeClass("error"); } };</code>
Abgesehen davon nennen wir die ursprüngliche offene Methode, ohne andere Operationen auszuführen.
Wenn Sie unseren Send -Abgeordneten erneut besuchen, ist es jetzt offensichtlich, wie Sie die Bedingungsprüfung beheben. Das Folgende ist die modifizierte Version:
<code class="language-javascript">var originalConsoleLog = console.log; console.log = function(text) { if (typeof text === "string" && text.indexOf("FeedbackBox:") === 0) { return; } originalConsoleLog.apply(console, arguments); }</code>
Schlussfolgerung
Was wir hier sehen, ist eine kurze Einführung zum Ändern des Verhaltens von Code zur Laufzeit mit Monkey -Patches. Aber was noch wichtiger ist, ich hoffe, dieser Beitrag gibt Ihnen eine Vorstellung davon, wie Sie mit Affenpatches umgehen können. Während der Patch selbst normalerweise einfach ist, ist es wichtig, die Idee zu haben, wie der Code zur Laufzeit angepasst werden kann.
Ich hoffe auch, dass Sie egal was Sie von Monkey -Patches halten, die Möglichkeit haben, die Schönheit der Verwendung dynamischer Sprachen zu erkennen, sodass Sie auch native Implementierungen zur Laufzeit dynamisch verändern können.
FAQs über den praktischen Monkey Patch (FAQ)
Monkey-Patches in JavaScript sind eine Technik, bei der das Verhalten integrierter oder benutzerdefinierter Objekte normalerweise durch Hinzufügen, Ändern oder Ändern des Prototyps des Objekts geändert wird. Dies ist eine Möglichkeit, das Verhalten des Codes zu erweitern oder zu ändern, ohne den ursprünglichen Quellcode zu ändern. Diese Technik kann verwendet werden, um die Reparatur, die Verbesserung der vorhandenen Funktionen und sogar zum Testen und Debugging -Zwecke zu verbessern.
Während das Konzept von Monkey -Patches in JavaScript und Python das gleiche ist - das Verhalten der Änderung oder Erweiterung von Objekten - unterscheidet sich die Implementierung aufgrund von Unterschieden in der Sprache selbst. In JavaScript werden Monkey -Patches normalerweise durchgeführt, indem der Prototyp eines Objekts geändert wird, während in Python dies durch Hinzufügen oder Ändern einer Klasse oder Instanzmethode durchgeführt wird. Die Flexibilität beider Sprachen ermöglicht das Monkey -Patchen, aber diese Technik sollte mit Vorsicht verwendet werden, um unerwartes Verhalten zu vermeiden.
Der Affenpatch ist ein leistungsstarkes Werkzeug, aber nicht ohne Kontroversen. Obwohl es Funktionen schnell ändern oder erweitern kann, ohne den ursprünglichen Quellcode zu ändern, kann dies auch zu unvorhersehbarem Verhalten und Konflikten führen, insbesondere bei Überbeanspruchung oder unangemessener. Daher wird häufig empfohlen, Monkey -Patches mit Vorsicht und Verantwortung zu verwenden und immer die potenziellen Auswirkungen auf die gesamte Codebasis zu berücksichtigen.
Das Hauptrisiko eines Monkey Patch besteht darin, dass es zu unvorhersehbarem Verhalten und Konflikten im Code führen kann. Da es das Verhalten vorhandener Objekte ändert, kann der Code unterbrechen, wenn an anderer Stelle in der Codebasis eine Patch -Methode verwendet wird. Es kann auch zu Verwirrung bei anderen Entwicklern führen, die sich der Modifikationen möglicherweise nicht bewusst sind. Daher ist es wichtig, alle Affenpatches klar und umfassend aufzuzeichnen.
Um eine Funktion in JavaScript sauber zu patchen, können Sie eine Wrapper um die ursprüngliche Funktion erstellen. Diese Wrapper -Funktion ruft die ursprüngliche Funktion auf und fügt das Verhalten nach Bedarf hinzu oder modifiziert sie dann. Auf diese Weise bleibt die ursprüngliche Funktion unverändert und das zusätzliche Verhalten ist klar getrennt, sodass der Code leichter zu verstehen und zu warten.
Ja, Monkey -Patches können als nützliches Tool zum Testen und Debuggen verwendet werden. Durch Ändern oder Erweiterung des Verhaltens einer Funktion oder Methode können Sie verschiedene Szenarien simulieren, Fehler injizieren oder Protokolle hinzufügen, um die Ausführung Ihres Codes zu verfolgen. Es ist jedoch wichtig, diese Patches im Produktionscode zu entfernen oder zu isolieren, um unerwartete Nebenwirkungen zu vermeiden.
In JavaScript spielen Prototypen eine entscheidende Rolle in Affenpatches. Da JavaScript eine prototypbasierte Sprache ist, verfügt jedes Objekt über einen Prototyp, der Eigenschaften und Methoden daraus erbt. Durch Ändern des Prototyps eines Objekts können Sie das Verhalten aller Instanzen dieses Objekts ändern. Dies ist die Grundlage für Monkey -Patches in JavaScript.
Der Einfluss von Affenpatches auf die JavaScript -Leistung ist normalerweise gering. Übermäßige oder unsachgemäße Verwendung von Monkey -Patches kann jedoch Leistungsprobleme verursachen. Wenn Sie beispielsweise gepatchte Methoden in Ihrem Code häufig verwenden, kann zusätzliches Verhalten die Ausführung verlangsamen. Verwenden Sie daher unbedingt Monkey -Patches mit Vorsicht und überwachen Sie die Leistung regelmäßig.
Ja, der Affenpatch kann verwendet werden, um integrierte JavaScript-Objekte zu erweitern. Durch Ändern des Prototyps des integrierten Objekts können Sie neue Methoden oder Eigenschaften hinzufügen, die für alle Instanzen des Objekts verfügbar sind. Dies sollte jedoch mit Vorsicht erfolgen, um Konflikte mit zukünftigen Versionen von JavaScript zu vermeiden, die dieselben Methoden oder Eigenschaften einführen können.
Es gibt mehrere Alternativen zu Monkey -Patches in JavaScript. Eine häufige Möglichkeit besteht darin, Kombinationen zu verwenden, in denen Sie ein neues Objekt erstellen, das das ursprüngliche Objekt enthält und das Verhalten hinzufügen oder überschreibt. Eine andere Möglichkeit besteht darin, die Vererbung zu verwenden, bei der Sie eine neue Klasse erstellen, die aus der ursprünglichen Klasse erbt und die Methode überschreibt. Diese Methoden können ähnliche Flexibilität bei Monkey -Patches bieten, jedoch mit einer besseren Einkapselung und weniger Konfliktrisiken.
Das obige ist der detaillierte Inhalt vonPragmatische Verwendungen von Affenpaticken in JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!