Maison >interface Web >js tutoriel >Utilisations pragmatiques du correctif de singe en javascript
Points de base
Cet article a été examiné par Moritz Kröger et Tom Greco. Merci à tous les pairs examinateurs de SitePoint pour avoir obtenu le contenu de SitePoint à son meilleur!
Avez-vous déjà utilisé du code tiers qui fonctionne bien, sauf pour une petite question qui vous rend fou? Pourquoi le Créateur a-t-il oublié de supprimer ces journaux de console ennuyeux? Ne serait-ce pas bien si cet appel API pouvait faire encore une chose? Si c'est le cas, vous savez que le maintien du mainteneur implémente vos modifications peut être difficile (ou impossible). Mais qu'en est-il de changer le code vous-même? Et si vous n'avez pas de code source et que vous ne voulez pas les héberger vous-même? Bienvenue dans le voyage mondial de Javascript Monkey Patch!
Dans cet article, nous apprendrons ce qu'est un patch de singe et parcourent différents exemples pour l'utiliser pour modifier la fonctionnalité d'un widget tiers pour répondre à nos besoins.
Qu'est-ce qu'un patch de singe?
Le patch de singe (MP) est une technique utilisée pour remplacer, étendre et même supprimer le comportement par défaut des segments de code sans modifier son code source d'origine. Cela se fait en remplaçant le comportement d'origine par la version fixe .
Cet article utilisera le widget de boîte de rétroaction existant qui affiche une fenêtre contextuelle simple et glissable (illustrée à l'image ci-dessous) contenant le formulaire de rétroaction.
Le code source a été modifié pour inclure des cas d'utilisation à utiliser comme cibles MP. L'objectif se réfère aux fonctions spécifiques, aux fonctionnalités ou à l'utilisation minimale de niveau que nous réparons. Une autre modification que j'ai apportée a été de supprimer l'expression de la fonction d'appel (iife) autour du code. Ceci est fait pour se concentrer sur la technologie MP.
Vous pouvez trouver l'intégralité de l'exemple de Plunker, y compris le patch de singe discuté dans cet article.
Le patch de singe n'est-il pas une mauvaise pratique?
Avant de commencer, indiquons clairement: oui, MP est considéré comme une mauvaise pratique - Evil eval , programmation impérative, structures de données variables, liaison bidirectionnelle, il est donc d'attente.
Si vous utilisez l'un ou l'autre, il y a très probablement un groupe assez important de personnes vous disant que vous faites quelque chose de mal et que ceci ou cela devrait être modifié pour s'adapter à de meilleures conditions. Mais comme toujours, il existe différents outils et technologies disponibles, et leur applicabilité varie dans des scénarios spécifiques. Parfois, quelque chose qui a l'air extrême, fou ou simplement mauvais peut être un dernier recours dans une situation particulière. Malheureusement, comme certaines pratiques sont considérées comme mauvaises, vous ne pouvez même pas trouver de nombreux articles pour décrire comment faire la mauvaise chose de la bonne manière. La situation décrite ici peut être contre nature, la pousser à l'extrême avec de faux widgets pour montrer votre choix. Ensuite, en tant que lecteur, vous devez décider si vous aimez ce que vous voyez. Si rien d'autre, après avoir lu cet article, vous aurez une meilleure compréhension pour vous opposer à MP.
cible du patch de singe
Avant de approfondir ces technologies, vérifions d'abord ce que nous voulons réaliser. Le widget modifié a une odeur de code et nous voulons résoudre ces problèmes.
Couleur d'arrière-plan codé en dur
Comme vous pouvez le voir, il définit la propriété de couleur arrière via la méthode jQuery CSS. C'est un problème car nous voulons le spécifier via des règles de feuille de style.
<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
Bloquer l'appel du serveur AD
<code class="language-javascript">FeedbackBox.prototype.init = function() { // 我们想要跳过的广告服务器调用 $.ajax('vendor/service.json', { method: 'GET' }).then(function(data) { console.log("FeedbackBox: AdServer contacted"); }); ... </code>Remarque: le code de démonstration simule les demandes AJAX sortantes pour les fichiers JSON dans Plunker, mais j'espère que vous comprenez cela.
Méthode de couverture
L'un des concepts clés de MP est d'obtenir des fonctions existantes et de les améliorer avant ou après avoir appelé le code d'origine en utilisant un comportement personnalisé. Mais appeler l'implémentation d'origine n'est pas toujours nécessaire, car parfois vous voulez simplement le remplacer par des actions personnalisées. Cette approche est idéale pour nous aider à résoudre le problème de la couleur d'arrière-plan à code dur.
L'emplacement où le MP est appliqué doit être chargé et fourni avec l'implémentation d'origine. Généralement, vous devez vous efforcer d'obtenir les changements aussi près que possible de votre objectif, mais n'oubliez pas que la mise en œuvre de l'objectif peut changer avec le temps. Quant à notre exemple, l'initialisation et MP iront au fichier main.js.
En regardant l'implémentation du widget, nous pouvons voir qu'il existe un objet de rétroaction comme racine du widget. Plus tard, la fonction ToggleError sera implémentée sur son prototype.
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) { if(isError) { obj.css("background-color", "darkgrey"); } else { obj.css("background-color", ""); } }</code>
Étant donné que JavaScript est un langage dynamique dont les objets peuvent être modifiés à l'exécution, tout ce que nous finirons par faire est de remplacer ToggleError par notre méthode personnalisée. La seule chose à noter est de garder la signature (nom et paramètres passés) le même.
<code class="language-javascript">FeedbackBox.prototype.init = function() { // 我们想要跳过的广告服务器调用 $.ajax('vendor/service.json', { method: 'GET' }).then(function(data) { console.log("FeedbackBox: AdServer contacted"); }); ... </code>
La nouvelle implémentation ajoute désormais simplement une classe d'erreur à l'élément donné, nous permettant de définir la couleur d'arrière-plan via CSS.
Méthode d'amélioration
Dans l'exemple précédent, nous avons vu comment remplacer la mise en œuvre d'origine en fournissant nos propres méthodes. D'un autre côté, le traitement des journaux de console doit simplement filtrer les appels spécifiques et les supprimer. La clé du succès est d'examiner le code que vous intégrez et d'essayer de comprendre son flux de travail. En règle générale, cela se fait en lançant la console du développeur dans le navigateur de votre choix et en jetant un coup d'œil à travers les ressources chargées, en ajoutant des points d'arrêt et en débogues les sections de code d'objet pour comprendre sa fonctionnalité. Cependant, cette fois, il vous suffit d'ouvrir l'implémentation dans l'exemple Plunker appelé fournisseur / jQuery.feedbackbox.js dans un autre onglet.
En regardant les messages de débogage, nous pouvons voir que chacun d'eux commence par FeedbackBox: . Ainsi, un moyen facile de réaliser ce que nous voulons est d'intercepter l'appel d'origine, de vérifier le texte fourni pour être écrit et d'appeler la méthode d'origine uniquement si elle ne contient pas d'invite de débogage.
Pour ce faire, stockons d'abord la console originale.log dans une variable pour une utilisation ultérieure. Là encore, nous employons l'implémentation d'origine avec notre implémentation personnalisée, qui vérifie d'abord si le texte de la propriété fourni est un type de chaîne, et si c'est le cas, vérifie s'il contient la sous-chaîne de rétroaction:. Si c'est le cas, nous ne ferons rien, sinon nous exécuterons le code de console d'origine en appelant sa méthode d'application.
Notez que cette méthode prend le contexte comme le premier paramètre, ce qui signifie que la méthode doit être appelée sur cet objet, ainsi qu'une variable d'argument magique. Ce dernier est un tableau de tous les paramètres transmis à l'origine à l'appel Console.log d'origine.
<code class="language-javascript">function FeedbackBox(elem, options) { this.options = options; this.element = elem; this.isOpen = false; } FeedbackBox.prototype.toggleError = function(obj, isError) { ... }</code>
Remarque: vous vous demandez peut-être pourquoi nous n'avons pas simplement transmis l'attribut de texte. Eh bien, Console.log peut en fait être appelé avec des paramètres infinis, qui seront finalement connectés à une seule sortie de texte. Ainsi, au lieu de définir tous ces paramètres (qui peuvent être très difficiles pour les possibilités infinies), nous faisons simplement transmettre tout le contenu entrant.
Intercepter les appels Ajax
Enfin, voyons comment résoudre le problème du serveur publicitaire. Regardons à nouveau la fonction d'init du widget:
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) { if(isError) { obj.css("background-color", "darkgrey"); } else { obj.css("background-color", ""); } }</code>
La première idée pourrait être d'ouvrir un navigateur et de rechercher comment remplacer le plugin jQuery. Selon la qualité de vos compétences de recherche, vous pouvez ou non trouver la bonne réponse. Mais arrêtons et réfléchissons à ce qui se passe ici. Peu importe ce que JQuery fait à sa méthode Ajax, il finit par créer un XMLHttpRequest natif à un moment donné.
Voyons comment cela fonctionne dans les coulisses. L'exemple le plus simple trouvé sur MDN nous montre ceci:
<code class="language-javascript">FeedbackBox.prototype.init = function() { // 我们想要跳过的广告服务器调用 $.ajax('vendor/service.json', { method: 'GET' }).then(function(data) { console.log("FeedbackBox: AdServer contacted"); }); ... </code>
Nous voyons une nouvelle instance XMLHttpRequest créée. Il a une méthode OnreadyStateChange qui ne nous soucie pas réellement, puis les méthodes ouvertes et envoyées. Très bien. Notre idée est donc de corriger la méthode d'envoi et de lui dire de ne pas effectuer d'appels à une URL spécifique.
<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, il s'avère que vous ne pouvez pas obtenir l'URL cible de l'objet lui-même. Oups. Alors que devons-nous faire? Nous le mettons sur l'objet. À la recherche de la première chance d'obtenir l'URL, nous pouvons voir que la méthode ouverte l'accepte comme le deuxième paramètre. Pour rendre l'URL disponible dans l'objet lui-même, commençons par MP Open Method.
Comme auparavant, nous stockons la méthode ouverte d'origine dans une variable pour une utilisation ultérieure. Ensuite, nous employons l'implémentation d'origine par une implémentation personnalisée. Étant donné que nous pouvons utiliser JavaScript (un langage dynamique), nous pouvons créer une nouvelle propriété à tout moment et le nommer _url, qui sera défini sur la valeur du paramètre passé.
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) { if(isError) { obj.addClass("error"); } else { obj.removeClass("error"); } };</code>
En dehors de cela, nous appelons la méthode ouverte d'origine sans effectuer d'autres opérations.
Revisiter notre Send MP, il est évident maintenant comment résoudre le chèque de condition. Ce qui suit est la version modifiée:
<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>
Conclusion
Ce que nous voyons ici est une brève introduction sur la modification du comportement du code lors de l'exécution à l'aide de correctifs de singe. Mais plus important encore, j'espère que ce post vous donnera une idée de la façon de gérer les correctifs de singe. Bien que le patch lui-même soit généralement simple, il est important d'avoir l'idée de régler le code à l'exécution.
Aussi, j'espère que peu importe ce que vous pensez des patchs de singe, vous avez la possibilité de voir la beauté de l'utilisation de langues dynamiques, qui vous permet de changer dynamiquement même les implémentations natives lors de l'exécution.
FAQ sur le patch de singe pratique (FAQ)
Les correctifs de singe en JavaScript sont une technique dans laquelle le comportement des objets intégrés ou définis par l'utilisateur est modifié, généralement en ajoutant, modifiant ou modifiant le prototype de l'objet. C'est une façon d'étendre ou de modifier le comportement du code sans modifier le code source d'origine. Cette technique peut être utilisée pour implémenter la réparation, améliorer les fonctions existantes et même à des fins de test et de débogage.
Alors que le concept de correctifs de singe dans JavaScript et Python est le même - le comportement de modification ou d'étendage d'objets - l'implémentation est différente en raison des différences dans le langage lui-même. Dans JavaScript, les correctifs de singe sont généralement effectués en modifiant le prototype d'un objet, tandis que dans Python, il se fait en ajoutant ou en modifiant une méthode de classe ou d'instance. La flexibilité des deux langues permet le correctif de singe, mais cette technique doit être utilisée avec prudence pour éviter un comportement inattendu.
Le patch de singe est un outil puissant, mais il n'est pas sans controverse. Bien qu'il puisse modifier ou étendre rapidement les fonctionnalités sans modifier le code source d'origine, cela peut également conduire à un comportement et à des conflits imprévisibles, en particulier lorsqu'ils sont surutilisés ou inappropriés. Par conséquent, il est souvent recommandé d'utiliser des correctifs de singe avec prudence et responsabilité, et envisagez toujours l'impact potentiel sur l'ensemble de la base de code.
Le principal risque de patch de singe est qu'il peut conduire à un comportement et à des conflits imprévisibles dans le code. Parce qu'il modifie le comportement des objets existants, il peut casser le code si une méthode correcée est utilisée ailleurs dans la base de code. Il peut également provoquer une confusion parmi les autres développeurs qui ne sont peut-être pas conscients des modifications. Par conséquent, il est important d'enregistrer des correctifs de singe clairement et de manière approfondie.
Pour corriger proprement une fonction en JavaScript, vous pouvez créer un wrapper autour de la fonction originale. Cette fonction de wrapper appellera la fonction d'origine, puis ajoutera ou modifiera le comportement au besoin. De cette façon, la fonction d'origine reste inchangée et le comportement supplémentaire est clairement séparé, ce qui rend le code plus facile à comprendre et à maintenir.
Oui, les correctifs de singe peuvent être utilisés comme un outil utile pour tester et déboguer. En modifiant ou en étendant le comportement d'une fonction ou d'une méthode, vous pouvez simuler différents scénarios, injecter des erreurs ou ajouter des journaux pour suivre l'exécution de votre code. Cependant, il est important de supprimer ou d'isoler ces correctifs dans le code de production pour éviter tout effet secondaire inattendu.
En JavaScript, les prototypes jouent un rôle crucial dans les patchs de singe. Étant donné que JavaScript est un langage basé sur un prototype, chaque objet a un prototype qui en hérite des propriétés et des méthodes. En modifiant le prototype d'un objet, vous pouvez modifier le comportement de toutes les instances de cet objet. C'est la base des correctifs de singe en JavaScript.
L'impact des correctifs de singe sur les performances JavaScript est généralement faible. Cependant, une utilisation excessive ou inappropriée de patchs de singe peut entraîner des problèmes de performance. Par exemple, si vous utilisez fréquemment des méthodes correctes dans votre code, un comportement supplémentaire peut ralentir l'exécution. Par conséquent, assurez-vous d'utiliser les correctifs de singe avec prudence et de surveiller régulièrement les performances.
Oui, le patch de singe peut être utilisé pour étendre les objets JavaScript intégrés. En modifiant le prototype de l'objet intégré, vous pouvez ajouter de nouvelles méthodes ou propriétés qui seront disponibles pour toutes les instances de l'objet. Cependant, cela devrait être fait avec prudence pour éviter les conflits avec les futures versions de JavaScript, qui peuvent introduire les mêmes méthodes ou propriétés.
Il existe plusieurs alternatives aux correctifs de singe en JavaScript. Un moyen courant consiste à utiliser des combinaisons, où vous créez un nouvel objet qui contient l'objet d'origine et d'ajouter ou d'écraser le comportement. Une autre façon consiste à utiliser l'héritage, où vous créez une nouvelle classe qui hérite de la classe originale et écrase la méthode. Ces méthodes peuvent fournir une flexibilité similaire aux patchs de singe, mais avec une meilleure encapsulation et moins de risque de conflit.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!