Maison >interface Web >js tutoriel >Utilisations pragmatiques du correctif de singe en javascript

Utilisations pragmatiques du correctif de singe en javascript

William Shakespeare
William Shakespeareoriginal
2025-02-17 12:52:10448parcourir

Pragmatic Uses of Monkey Patching in JavaScript

Points de base

  • Patch Monkey (MP) dans JavaScript est une technologie qui permet aux programmeurs de remplacer, d'étendre ou de supprimer le comportement par défaut des segments de code sans modifier leur code source d'origine.
  • Bien que MP soit souvent considéré comme une mauvaise pratique, il peut être utilisé comme un outil utile pour modifier le code tiers pour répondre aux besoins spécifiques, surtout si le code source d'origine ne peut pas être modifié.
  • MP peut être utilisé pour écraser les fonctions existantes avec un comportement personnalisé, améliorer les méthodes en ajoutant un comportement personnalisé avant ou après le code d'origine, ou interceptant les appels AJAX pour modifier leur comportement.
  • MP doit être utilisé avec prudence, car il peut provoquer un comportement et des conflits imprévisibles dans le code, surtout si des méthodes correctes sont utilisées ailleurs dans la base de code.
  • Malgré les risques potentiels, MP peut toujours être un outil puissant pour tester, déboguer et mettre en œuvre des réparations, mettant en évidence la flexibilité et la nature dynamique du JavaScript en tant que langage de programmation.

Pragmatic Uses of Monkey Patching in JavaScript

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.

Pragmatic Uses of Monkey Patching in JavaScript

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

Le premier est une méthode appelée ToggleError, qui devrait modifier la couleur d'arrière-plan de l'élément en fonction du paramètre booléen

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

Lors du développement de widgets, utilisez le journal de la console pour inviter le développeur à ce qui s'exécute actuellement. Cela peut être une bonne approche pendant le développement, mais ce n'est certainement pas la meilleure approche de l'utilisation de la production. Nous devons donc trouver un moyen de supprimer toutes ces instructions de débogage.

Bloquer l'appel du serveur AD

Le widget est génial, mais il a un comportement étrange. Chaque fois que le script est initialisé, il fait une demande à un serveur d'annonces étranges et affiche du contenu de ballonnement inutile sur notre page.

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

Quel est le concept de patch de singe en JavaScript?

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.

Quelle est la différence entre les correctifs de singe dans JavaScript et Python?

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-il considéré comme une bonne pratique en JavaScript?

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.

Quels sont les risques potentiels des correctifs de singe?

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.

Comment corriger proprement une fonction en JavaScript?

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.

Les correctifs de singe peuvent-ils être utilisés pour tester et déboguer?

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.

Quel rôle le prototype joue-t-il dans les correctifs de singe en javascript?

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.

Comment le patch de singe affecte-t-il les performances 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.

Les correctifs de singe peuvent-ils être utilisés pour étendre les objets JavaScript intégrés?

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.

Quelles sont les alternatives aux correctifs de singe en javascript?

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn