ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptのサルパッチングの実用的な使用

JavaScriptのサルパッチングの実用的な使用

William Shakespeare
William Shakespeareオリジナル
2025-02-17 12:52:10438ブラウズ

Pragmatic Uses of Monkey Patching in JavaScript

コアポイント

    JavaScriptのMonkey Patch(MP)は、プログラマーが元のソースコードを変更せずにコードセグメントのデフォルト動作をオーバーライド、拡張、または抑制できるようにするテクノロジーです。
  • MPはしばしば悪いプラクティスと見なされますが、特に元のソースコードを変更できない場合は、特定のニーズに合わせてサードパーティコードを変更するための便利なツールとして使用できます。
  • MPを使用して、既存の関数をカスタム動作で上書きしたり、元のコードの前後にカスタム動作を追加したり、Ajax呼び出しをインターセプトして動作を変更したりすることができます。
  • 特にパッチされた方法がコードベースの他の場所で使用されている場合、コードの予測不可能な動作と競合を引き起こす可能性があるため、
  • MPは注意して使用する必要があります。
  • 潜在的なリスクにもかかわらず、MPは、プログラミング言語としてのJavaScriptの柔軟性と動的な性質を強調し、修理のテスト、デバッグ、および実装の強力なツールになります。

Pragmatic Uses of Monkey Patching in JavaScript

この記事は、MoritzKrögerとTom Grecoによってレビューされました。 SetePointのすべてのピアレビューアーズに感謝します。

あなたを狂わせる1つの小さな質問を除いて、うまく機能するサードパーティのコードを使用したことがありますか?作成者がこれらの迷惑なコンソールログを削除するのを忘れたのはなぜですか?そのAPI呼び出しがもう一つのことをすることができれば、それはいいことではないでしょうか?もしそうなら、あなたはメンテナーにあなたの変更を実装することは困難な(または不可能)ことができることを知っています。しかし、コードを自分で変更するのはどうですか?ソースコードがなく、自分でホストしたくない場合はどうなりますか? JavaScriptモンキーパッチの世界の旅へようこそ!

この記事では、モンキーパッチが何であるかを学び、いくつかの異なる例を踏んで、それを使用してサードパーティウィジェットの機能を変更してニーズに合わせて変更します。

モンキーパッチとは何ですか?

モンキーパッチ(MP)は、元のソースコードを変更せずにコードセグメントのデフォルトの動作をオーバーライド、拡張、さらには抑制するために使用される手法です。これは、元の動作を

fix

バージョンに置き換えることによって行われます。 この記事では、フィードバックフォームを含むシンプルでスワイプ可能なポップアップウィンドウ(下の画像に示す)を表示する既存のフィードバックボックスウィジェットを使用します。

Pragmatic Uses of Monkey Patching in JavaScript ソースコードは、MPターゲットとして使用するためのユースケースを含めるように変更されています。目標とは、特定の機能、機能、またはパッチを適用する最小レベルの使用法を指します。

私が行った別の変更は、コードの周りにコール関数式(IIFE)を削除することでした。これは、MPテクノロジーに焦点を当てるために行われます。 この記事で説明したモンキーパッチを含む、プランカーで例全体を見つけることができます。

モンキーのパッチは悪い練習ではありませんか?

開始する前に、それを明確にしましょう:はい、MPは悪い実践と見なされます。 これらのいずれかを使用する場合、あなたが何か間違っていること、そしてこれがより良い条件に合うように変更するべきだと言っている人々のグループが非常に大きなグループがあります。しかし、いつものように、さまざまなツールとテクノロジーが利用可能であり、それらの適用性は特定のシナリオで異なります。時には、極端に、クレイジー、または単に悪いように見えるものが、特定の状況での最後の手段になることがあります。残念ながら、一部のプラクティスは悪いと見なされているため、間違ったことを正しい方法で行う方法を説明する多くの記事を見つけることさえできません。

ここで説明する状況は不自然である可能性があります。あなたの選択を示すために、偽のウィジェットで極端に押し込みます。それから、読者として、あなたが見るものが好きかどうかを決める必要があります。他に何もなければ、この記事を読んだ後、MPに反対するために、よりよく理解できます。 モンキーパッチのターゲット

これらのテクノロジーをより深く掘り下げる前に、最初に達成したいことをチェックしてみましょう。変更されたウィジェットにはコード臭いがあり、これらの問題を解決したいと考えています。

ハードコーディングされた背景色 最初は、Booleanパラメーターに基づいて要素の背景色を変更する必要があるToggleerrorと呼ばれるメソッドです。

ご覧のとおり、jQueryメソッドCSSを介して背景色のプロパティを設定します。 StyleSheetルールを使用して指定したいため、これは問題です。

Nevil Console Log

ウィジェットを開発するときは、コンソールログを使用して、現在実行中の開発者に促します。これは開発中の良いアプローチかもしれませんが、確かに生産使用における最良のアプローチではありません。したがって、これらすべてのデバッグステートメントを削除する方法を見つける必要があります。

<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.css("background-color", "darkgrey");
  } else {
    obj.css("background-color", "");
  }
}</code>
ブロック広告サーバーコール

ウィジェットは素晴らしいですが、奇妙な動作があります。スクリプトが初期化されるたびに、奇妙な広告サーバーにリクエストを行い、ページに不要なブロートコンテンツを表示します。

注:DEMOコードは、PlunkerでJSONファイルの発信ajaxリクエストをシミュレートしますが、これを理解することを願っています。

カバレッジ方法
<code class="language-javascript">FeedbackBox.prototype.init = function() {
  // 我们想要跳过的广告服务器调用
  $.ajax('vendor/service.json', {
    method: 'GET'
  }).then(function(data) {
    console.log("FeedbackBox: AdServer contacted");
  });

  ...
</code>

MPの重要な概念の1つは、既存の機能を取得し、カスタム動作を使用して元のコードを呼び出す前または後にそれらを強化することです。ただし、元の実装を呼び出すことは必ずしも必要ではありません。なぜなら、カスタムアクションに置き換えるだけであることがあるからです。このアプローチは、ハードコーディングされた背景色の問題を解決するのに役立つのに最適です。

MPが適用される場所は、元の実装でロードされ、提供する必要があります。一般的に、目標をできるだけ目標に近づけるように努力する必要がありますが、目標の実装は時間とともに変化する可能性があることを忘れないでください。この例に関しては、初期化とMPはファイルmain.jsに移動します。

ウィジェットの実装を見ると、ウィジェットのルートとしてフィードバックボックスオブジェクトがあることがわかります。その後、ToggleError関数がそのプロトタイプに実装されます。

<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.css("background-color", "darkgrey");
  } else {
    obj.css("background-color", "");
  }
}</code>

JavaScriptは実行時にオブジェクトを変更できる動的言語であるため、最終的に行うことになるのは、トググルエラーをカスタムメソッドに置き換えることだけです。注意すべき唯一のことは、署名(名前と渡されたパラメーター)を同じに保つことです。

<code class="language-javascript">FeedbackBox.prototype.init = function() {
  // 我们想要跳过的广告服务器调用
  $.ajax('vendor/service.json', {
    method: 'GET'
  }).then(function(data) {
    console.log("FeedbackBox: AdServer contacted");
  });

  ...
</code>

新しい実装により、指定された要素にエラークラスを追加するだけで、CSSを介して背景色を設定できます。

拡張方法

前の例では、独自の方法を提供することにより、元の実装をオーバーライドする方法を見ました。一方、コンソールログの処理は、特定の呼び出しを除外して抑制するだけです。成功の鍵は、埋め込んだコードを調べて、そのワークフローを理解しようとすることです。通常、これは、選択したブラウザで開発者コンソールを起動し、ロードされたリソースを覗き、ブレークポイントを追加し、オブジェクトコードセクションをデバッグして機能性を理解することで行われます。ただし、今回は、別のタブでVendor/jQuery.feedbackbock.jsというプランカーの例で実装を開く必要があります。

デバッグメッセージを見ることで、それぞれがフィードバックボックス:で始まることがわかります。したがって、私たちが望むものを達成する簡単な方法は、元の呼び出しを傍受し、記載されている指定されたテキストをチェックし、デバッグプロンプトが含​​まれていない場合にのみ元の方法を呼び出すことです。

これを行うには、最初に元のConsole.logを変数に保存して、後で使用しましょう。繰り返しになりますが、カスタム実装で元の実装をオーバーライドします。これは、提供されたプロパティテキストが文字列タイプであるかどうかを最初にチェックします。もしそうなら、サブストリングフィードバックボックスが含まれているかどうかを確認します。もしそうなら、私たちは何もしません。そうしないと、Applyメソッドを呼び出すことにより、元のコンソールコードを実行します。

このメソッドは、コンテキストを最初のパラメーターとして取得することに注意してください。つまり、メソッドはそのオブジェクトで呼び出される必要があることを意味します。後者は、元々元のConsole.logコールに渡されたすべてのパラメーターの配列です。

<code class="language-javascript">function FeedbackBox(elem, options) {
  this.options = options;  
  this.element = elem;  
  this.isOpen = false;
}

FeedbackBox.prototype.toggleError = function(obj, isError) {
  ...
}</code>
注:なぜ私たちが単にテキスト属性を転送しなかったのか疑問に思うかもしれません。まあ、Console.logは実際に無限のパラメーターで呼び出すことができ、最終的には単一のテキスト出力に接続されます。したがって、これらすべてのパラメーターを定義する代わりに(無限の可能性にとって非常に難しい場合があります)、すべての着信コンテンツを転送するだけです。

ajax calls 最後になりましたが、広告サーバーの問題を解決する方法を見てみましょう。ウィジェットのinit機能をもう一度見てみましょう:

<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.css("background-color", "darkgrey");
  } else {
    obj.css("background-color", "");
  }
}</code>

最初のアイデアは、ブラウザを開き、jQueryプラグインをオーバーライドする方法を検索することです。検索スキルがどれだけ優れているかに応じて、正しい答えを見つける場合とそうでない場合があります。しかし、ここで何が起こっているのかを止めて考えましょう。 jQueryがAjaxメソッドに対して何をしていても、ある時点でネイティブXMLHTTPREQUESTを作成することになります。

舞台裏でどのように機能するか見てみましょう。 MDNで見つかった最も単純な例は、これを示しています:

<code class="language-javascript">FeedbackBox.prototype.init = function() {
  // 我们想要跳过的广告服务器调用
  $.ajax('vendor/service.json', {
    method: 'GET'
  }).then(function(data) {
    console.log("FeedbackBox: AdServer contacted");
  });

  ...
</code>

新しいxmlhttprequestインスタンスが作成されています。実際には気にしないredidedStateChangeメソッドがあり、オープンアンドセンドメソッドがあります。とても良い。したがって、私たちのアイデアは、送信方法にパッチを当て、特定のURLへの呼び出しを実行しないように指示することです。

<code class="language-javascript">function FeedbackBox(elem, options) {
  this.options = options;  
  this.element = elem;  
  this.isOpen = false;
}

FeedbackBox.prototype.toggleError = function(obj, isError) {
  ...
}</code>

わかりました、オブジェクト自体からターゲットURLを取得できないことがわかります。おっと。それでは、私たちは何をすべきですか?オブジェクトに置きます。 URLを取得する最初のチャンスを探して、Openメソッドが2番目のパラメーターとして受け入れることがわかります。オブジェクト自体でURLを使用できるようにするには、MP Openメソッドから始めましょう。

前と同様に、元のオープンメソッドを後で使用するために変数に保存します。次に、カスタム実装で元の実装をオーバーライドします。 JavaScript(動的言語)を使用できるため、いつでも新しいプロパティを作成し、_urlに名前を付けることができます。これは、渡されたパラメーターの値に設定されます。

<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.addClass("error");
  } else {
    obj.removeClass("error");
  }
};</code>
これとは別に、他の操作を実行せずに元のオープンメソッドを呼び出します。

送信MPを再検討すると、状態チェックを解決する方法が明らかになりました。以下は変更されたバージョンです:

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

結論

ここで見られるのは、モンキーパッチを使用して実行時にコードの動作を変更することについての簡単な紹介です。しかし、もっと重要なことは、この投稿が猿のパッチに対処する方法のアイデアを提供することを願っています。パッチ自体は通常簡単ですが、実行時にコードを調整する方法を理解することが重要です。

また、モンキーパッチについてどう思うかに関係なく、動的言語を使用することの美しさを見る機会があることを願っています。これにより、実行時にネイティブの実装も動的に変更できます。

実用的なモンキーパッチ(FAQ)

についての

FAQ JavaScriptのモンキーパッチの概念は何ですか?

JavaScriptのモンキーパッチは、通常、オブジェクトのプロトタイプを追加、変更、または変更することにより、組み込みまたはユーザー定義のオブジェクトの動作が変更される手法です。これは、元のソースコードを変更せずにコードの動作を拡張または変更する方法です。この手法は、修理、既存の機能の強化、さらにはテストやデバッグの目的でさえ実装するために使用できます。

JavaScriptとPythonのサルパッチの違いは何ですか?

JavaScriptとPythonのモンキーパッチの概念は同じですが、オブジェクトの変更または拡張の動作 - 言語自体の違いにより実装は異なります。 JavaScriptでは、モンキーパッチは通常、オブジェクトのプロトタイプを変更することによって行われますが、Pythonでは、クラスまたはインスタンスメソッドを追加または変更することで行われます。両方の言語の柔軟性により、サルのパッチが可能になりますが、この手法は、予期しない動作を避けるために注意して使用する必要があります。

モンキーパッチはJavaScriptの良い練習と見なされていますか?

モンキーパッチは強力なツールですが、論争がないわけではありません。元のソースコードを変更せずに機能を迅速に変更または拡張できますが、特に過剰使用または不適切な場合、予測不可能な動作や競合にもつながる可能性があります。したがって、多くの場合、サルパッチを慎重に責任を負い、常にコードベース全体に潜在的な影響を考慮することをお勧めします。

モンキーパッチの潜在的なリスクは何ですか?

モンキーパッチの主なリスクは、コードの予測不可能な動作と対立につながる可能性があることです。既存のオブジェクトの動作を変更するため、パッチされたメソッドがコードベースの他の場所で使用されている場合、コードを破ることができます。また、変更を認識していない他の開発者の間で混乱を引き起こす可能性があります。したがって、猿のパッチを明確かつ包括的に記録することが重要です。

JavaScriptで関数をきれいにパッチする方法は?

JavaScriptで関数をきれいにパッチすると、元の関数の周りにラッパーを作成できます。このラッパー関数は、元の関数を呼び出し、必要に応じて動作を追加または変更します。このようにして、元の関数は変更されておらず、追加の動作が明確に分離されているため、コードの理解と維持が容易になります。

モンキーパッチは、テストとデバッグに使用できますか?

はい、モンキーパッチは、テストとデバッグに役立つツールとして使用できます。関数またはメソッドの動作を変更または拡張することにより、さまざまなシナリオをシミュレート、エラーを注入するか、ログを追加してコードの実行を追跡できます。ただし、予期しない副作用を回避するために、これらのパッチを生産コードで削除または隔離することが重要です。

JavaScriptのモンキーパッチでプロトタイプはどのような役割を果たしますか?

JavaScriptでは、モンキーパッチでプロトタイプが重要な役割を果たします。 JavaScriptはプロトタイプベースの言語であるため、各オブジェクトにはプロパティとメソッドを継承するプロトタイプがあります。オブジェクトのプロトタイプを変更することにより、そのオブジェクトのすべてのインスタンスの動作を変更できます。これは、JavaScriptのサルパッチの基礎です。

モンキーパッチは、JavaScriptのパフォーマンスにどのように影響しますか?

JavaScriptのパフォーマンスに対するモンキーパッチの影響は通常、小さいです。ただし、モンキーパッチの過剰または不適切な使用は、パフォーマンスの問題を引き起こす可能性があります。たとえば、コードでパッチされたメソッドを頻繁に使用する場合、追加の動作は実行を遅くする可能性があります。したがって、慎重にモンキーパッチを使用し、定期的にパフォーマンスを監視してください。

モンキーパッチを使用して、組み込みのJavaScriptオブジェクトを拡張できますか?

はい、モンキーパッチを使用して、組み込みのJavaScriptオブジェクトを拡張できます。組み込みオブジェクトのプロトタイプを変更することにより、オブジェクトのすべてのインスタンスで使用できる新しいメソッドまたはプロパティを追加できます。ただし、これは、同じ方法またはプロパティを導入する可能性のあるJavaScriptの将来のバージョンとの対立を避けるために注意して行う必要があります。

JavaScriptのサルパッチの代替品は何ですか?

JavaScriptにはサルパッチにいくつかの代替品があります。一般的な方法は、組み合わせを使用することです。ここでは、元のオブジェクトを含む新しいオブジェクトを作成し、動作を追加または上書きします。別の方法は、元のクラスから継承してメソッドを上書きする新しいクラスを作成する継承を使用することです。これらの方法は、モンキーパッチに同様の柔軟性を提供できますが、カプセル化が改善され、競合のリスクが少なくなります。

以上がJavaScriptのサルパッチングの実用的な使用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。