JavaScriptのジェネリックの実装問題はあなた""JavaScriptでのJavaやCなどのプログラミングの概念を求めている#。理論プログラミング言語のジェネリックを実装する ジェネリック医薬品。ジェネリック医薬品の背後にある考え方や方法は、識別子は、クラスやメソッドで操作されている一般的な型として定義されるコードを記述することです。たとえば、次のコードは、JavaまたはC言語で一般的なクラスになるだろう#: クラスのコンテナ コンテナクラスを参照できる他のタイプの一般的なパラメータは、タイプがあります。そして、コンテナ、_managedデータメンバの宣言の中で、一般的なパラメータとしては、同じタイプです。抽象的な概念では、コンテナの任意のタイプを管理します。JavaScriptプログラマは、コードを見てかもしれないと思う。"ねえ、私はJavaScriptが既にこれを持っている!"ここでは、同じコードを、JavaScriptで、この時間は: ファンクションコンテナ()(this._managed / *任意のタイプ* /) レシピ2-8に示すように、参照することができますベースのカモを入力するか値アヒルの入力に基づく。 JavaScriptを"ジェネリック"を実装するプリプロセッサを実装するようなので、我々は価値をベース鴨の入力です。次のコード例では何が間違って行くことができますを示していますときにミックス値と参照カモ一緒に入力: プロキシ:("プロキシをすることはできません存在しないメソッド(インスタンス、funcIdentifier、newFunc)(場合に(!インスタンス[funcIdentifier])(スロー新しいError関数("+ funcIdentifier + ")");)eval("ヴァールgeneratedOrigFunc ="+インスタンス[ funcIdentifier]値toString()); eval("ヴァールgeneratedProxyFunc ="+ newFunc.toString());インスタンス[funcIdentifier] =関数()( ヴァールorigFunc = generatedOrigFunc; ヴァールproxyFunc = generatedProxyFunc;ヴァール引数=新しいArray();(ヴァールc1 = 0; c1"のarguments.length; c1 + +)(args.push(引数[c1])のため;)args.push(origFunc);(引数)args.push ;、(これは、引数);))proxyFunc.apply このソースコードはどのようにではなくProxyパターンの実装を記述する方法の例です。実装の問題は、太字のコードで表示されます。太字のコードの開始時に2つのeval文は、generatedOrigFuncとgeneratedProxyFunc変数の値が生成されています。組み込み関数インスタンス[funcIdentifier]、変数を参照されては、と閉鎖するには、origFuncとproxyFunc変数の参照が行われますため、適切な変数は、Proxyパターンの概念は、ときにメソッドが呼び出された場合は、最初の関数を参照呼び出しし、それを関数origFuncによって参照されるコールproxyFuncによる。ためproxyFunc最初に呼び出されると、データの前処理や後処理する能力があります。
コードとしては、Proxyパターンの1つのアプリケーションで動作する記述が、もし、プロキシのパターンを複数回適用され、失敗します。たとえば、すでに適用さProxyパターンのProxyパターンの生成されたコードを埋め込むことを想像。このコードは、"落とし穴の例JavaScriptのコードの"一部です。密接にgeneratedOrigFuncとgeneratedProxyFunc変数の宣言を見て何を参照しているか?エラーを理解するには、上のプロキシのコードを考えて左側のプロキシの実装1(PI1)やプロキシの実装2(地磁気)の右上のコードである。場合、一般的な呼び出しが行わ希望PI1、イベントの次のシーケンスを呼び出していた: 1。 PI1と呼ばれます。 2。 PI1のproxyFuncと呼ばれます。 3。 PI1のorigFuncは、地磁気に呼び出されます。 4。 地磁気のproxyFuncは、PI1のproxyFuncに呼び出されます。 5。 PI1のproxyFunc、PI1のorigFunc呼び出しと呼ばれるこれらの手順に従えば、あなたは再帰行われていることがわかります。再帰generatedOrigFuncとgeneratedProxyFunc変数が宣言されている方法が原因の一つです。これらの変数は、スコープなしで宣言されているため、プロキシのスコープ関数evalのコードの参照を使用してamixです。ため、いくつかの変数をシリアル化され、他はありません。我々はここで、"ジェネリック医薬品"を表し、Cプリプロセッサのような解決を望むが、この悪い習慣は、所望の型と識別子の交換物理。我々は、テンプレートシステムしたくない。テンプレートシステムとして説明される次のとおり: (ヴァールカウント"%= 0;カウント"10;カウント+ +)(%"シリーズ["%=数%"] = GenSeries("%=数%")<%}%> これは、コードの可読性を劇的に減少し、私たちは、必要に必要な一般的にされていないではありません。 JavaScriptのコードの動的な言語であり、多くのテンプレートのコード内に実装することができますを構築します。これ以上画像の目的については、変数の値を使用して参照を使用してから変更します。ソリューションを実装することは難しいの簡素化、単一のメソッドに単一のメソッド呼び出しを使用してProxyパターンを聞かせ、以下のとおり。 ソース: /サイト/ルート/ ajaxrecipes / javascriptに/ generics.html関数EmbeddedReplace()(ヴァールfunc = __toCall;情報("置換"、"こんにちは"); func()の;) EmbeddedReplace関数のローカル変数は、funcを宣言しています。 funcは、ローカル変数を参照する__toCall変数です。 funcの宣言の後には、info関数を呼び出すことです。最後の関数呼び出しfuncには、__toCallするための関数を呼び出すことです。よりも、グローバル変数の単独__toCallの使い方を見てから、多くの宣言は、他のことは知らない。このレシピの範囲については、__toCallが置き換えられる識別子です。 JavaScriptの拡張を呼び出すとすると(私は詳細について説明しますまもなく): EmbeddedReplace = Generics.expand(EmbeddedReplace、(__toCall:関数()(情報("置換"、"ハロー");}}); EmbeddedReplace置き換え(); Generics.expandメソッドは2つのパラメータがあります。最初のパラメータは、その実装を変更しているがEmbeddedReplace関数です。 2番目のパラメータは、識別子をどのように置換されますを表すオブジェクト構造体です。オブジェクトの構造などは、プロパティの識別子、および値は、プロパティに関連付けられて置換するための識別子を定義し、置換後の値が定義されます。注意してください すべてのコードをここに提示を使用してプログラムの技術標準のJavaScript。あなたは、編集者を混乱させると、より信頼性保守性のコードをビルドするには複雑に特別なバッファやタグを使用する必要はありません。際Generics.expandメソッドの実行が完了したら、次の関数の宣言が生成されます: 関数GeneratedEmbeddedReplace()(ヴァールfunc =(関数()(情報("置換"、"こんにちは");)))に置き換え;情報("置換"、"こんにちは"); func()の;) 生成されたバッファを私たちが期待する、とされている現象は私たちが期待しています。時GeneratedEmbeddedReplaceと呼ばれ、組み込み関数が呼び出されます。比較のために、見てみましょうどのようにこの組み込み機能を拡張せずに働いていること: 関数__toCall()(情報("置換"、"こんにちは")に置き換え;)関数EmbeddedReplace()(ヴァールfunc = __toCall;情報("置換"、"こんにちは"); func()の;) を呼び出すGeneratedEmbeddedReplace __toCall関数を呼び出すように振る舞い、見て、展開例のように感じています。しかし、どうしてこんなことをすればいい?参照膨張基づいて、すべてに拡大されていません。単にグローバル変数は、実行時に割り当てることができます(__toCall)を作成している。値と型の拡張は、1つ別のと競合しないよう、異なる機能を持つ複数の機能を持つことができます。ため、動作を代入することによって、状況はレシピ2-14で説明に実行することができますが機能を共有されて決定されます。 If関数を共有している場合は、関数の機能が変更される場合、競合が発生することができます。または、別のことを、別の時間の状況は、関数を1つの事1時間しないことができます。 "今一だけど、"問題は、次のコードのシナリオを考えます後は説明するには: 関数__toCall()(情報("置換"、"こんにちは")に置き換え;)関数EmbeddedReplace()(情報("置換"、"ハロー); __toCall();)()(EmbeddedReplace発信機能"(); __toCall =関数()()EmbeddedReplace();) ときに発信者と呼ばれ、最初の呼び出しのいくつかの出力結果EmbeddedReplaceする。次に__toCall、再割り当てされ、他の出力でEmbeddedReplace再度結果を呼び出して生成されるのかもしれない。これは、目的の効果ですが、ほとんどがされていない可能性が高い。この問題を解決する一つの方法はJavaScriptの動的な機能のご利用を制限することです。しかし、僕が尋ねると、この時点で、なぜあなたは、JavaScriptおよびAjaxを使用している?私の意見では、JavaScriptおよびAjaxとプログラミングの進化を表すため、あなたはそれらの動的挙動の機能を使用する必要があります。 EmbeddedReplaceし、EmbeddedReplaceに影響はなかっただろう__toCall変更を拡大していた。そして、この何をするときにJavaScriptのコードを書くことを考慮する必要があります。ときには、および参照を使用する時、これらのJavaScriptのジェネリック提案のような拡張を使用します。私はもう一つのポイントを追加したいと思います。これは親指のルールはないが、考え方は、特定のコンテキストでは、その場所があることができます。アプリケーションでの支払いは現在の1日の金利に基づいて計算される書面を想像。ほとんどのプログラミング言語では、現在の金利支払がロードされると、実行時に割り当てられた変数になります。 JavaScriptのジェネリックとの動作を使用してベースのコードは、次の拡張コードが使用できます: 関数CalculateInterestPayment(金額)(戻り量* 0.04;) このコードは、他のプログラミング言語と呼んでいる ハードコードされた。これは、数0.04は、アプリケーションにコンパイルされ、変更することはできませんがハードコーディングされたとみなされます。しかし、ここでの動作の利点をベースコード:ハードコーディングされた値を変更することは簡単ですJavaScriptのジェネリック薬を使用して伝統的なプログラミングモデルをするときに何の意味一切していないする必要はありません保つことです。 ときにデータがハードコーディングされたプログラミング方法を使用する 読み取り部分よりも書かれている場合、またはデータをより頻繁に読み取られます。データをハードディスク持つコード化されたパフォーマンスの向上、より多くの柔軟性を提供し、することができますし、アルゴリズムを簡素化します。今日のJavaScriptのジェネリック医薬品を使用して、その利子計算を単純な数値ですが、明日の計算では、スライドのルールが処理されている量に基づいて使用して化合物の計算されることができます。説明することは、理由、方法、および、JavaScriptが"ジェネリックは、"私は今"の実装方法JavaScriptを"ジェネリック医薬品をカバーします。これは、検索を含み、バッファ内の識別子を置き換えることは非常に単純なプロセスです。完全な実装を次のとおりです。 ソース: /サイト/ルート/スクリプト/ヴァールジェネリック=(展開:(toProcess)ops.singleSerialize =(toProcess、itemsToInject)(ヴァールbufferToProcess関数common.js; itemsToInjectで(itemToReplace)(ヴァールrecurFind =関数(startIndexに)(ヴァールオフセット= bufferToProcess.indexOf(itemToReplace、startIndexが);場合(== -1オフセット)(を返す;)ヴァール左側= bufferToProcess.slice(0、オフセット);ヴァール右側= bufferToProcess.slice(オフセット+ itemToReplace.length);ヴァール中間=(itemsToInject [itemToReplace]); bufferToProcess = +真ん中+右;オフセット+ +;(オフセット);)recurFind(0);)ヴァールgenBuffer ="ヴァール分類="recurFind + bufferToProcess +"左ops.simpleSerialize;"; (genBuffer);リターン分類;))eval 最初のバッファに変換するにはJavaScriptのオブジェクトを展開するには、オブジェクトがあります。バッファに任意のJavaScriptオブジェクトの変換、メソッドops.singleSerialize及び前条の例の場合には、バッファにtoProcessパラメータに変換します。バッファへの変換後は、識別子を見つけるとループを使って交換のプロセスが開始されます。ループの各反復でitemToReplace変数に格納されbufferToProcessに置き換えるための識別子です。ループでは、recurToFind変数の参照は、再帰的に呼び出される関数です。再帰の目的は、段階的に置き換えるには、識別子のためのバッファを検索します。 注意してください 再帰戦略のレシピ2-6で覆われている。bufferToProcess以内に識別子を見つけるためには、IndexOfメソッドを使用します。 indexOfを2つのパラメータ:最初のパラメータを見つけるために、識別子、および2番目のパラメータですが検索を開始するインデックスです。場合はindexOfをし、-1の値と、再帰が停止しますが返される識別子を見つけることはありません。場合はindexOfを、その識別子を見つけるとここでの識別子が返されます開始のインデックスを返します。が、バッファの左部分と右の部分に分割されている識別子が見つかりました。左と右の部分は、テキストに置き換えられますし、組み合わせて新しいbufferToProcessが作成されるときは、識別子が見つかった場合、バッファの拡張と見なされます。最後の残りの手順は、オブジェクトのインスタンスには、バッファに変換することです。バッファへの変換の問題のため実行を返しますeval(bufferToProcess)コマンドは、予測不可能なシナリオにつながる可能です。変換bufferToProcess予測分類変数への代入と連結され、確認してください。その時、新しいバッファはevalステートメントを使用して実行されると、ローカル変数の分類インスタンス化され、それを呼び出し元に返されることができます。コードを展開して実装するJavaScriptを"ジェネリック"は比較的簡単ですが、効果は奥が深い。ときにJavaScriptの"ジェネリック医薬品を使用して、"心の中で、次の点を維持: •JavaScript参照実装するために、多くの場合、十分な簡単です。しかし、レシピ2-14を指摘し、参照"の問題は、"知っておかなければポーズを行う。 •現在のすべての参照を使用して、すべてのevalを用いての間に決定を下す必要がある。 "すべて"ここアプリケーション全体が、参照していないタイプまたは関数のスコープ内のすべての。 eval文で参照を混在させないでください。行うので、問題の原因となります。 •全体的に、あなたのコードをより堅牢で安定した場合は、eval -テクニックのように使用します。参考文献単純なケースの場合にも動作する場合、あなたのコードを埋め込むコードを複数回アクセスし、エラーが発生することができます。 参照を使用•、あなたと同じ変数は、同じコードは、コードの複数の部分が参照の危険性を実行します。これにより、破損が発生することができます 過小評価すべきではない。 なぜなら、もしあなたが、関数またはオブジェクトのシリアル化を使う•eval -文のように簡単に、あなたのコードの現在の状態を取得し、その問題とは何かに従うことができるのデバッグができます。場合は、参照を使用すると、デバッガが必要になりますと、実行時に、その動作を決定するコードで、デバッグ、退屈することができます。 このレシピで説明するよう•を使用してJavaScriptを"ジェネリック"IDEです。フレンドリーなので、手動でバッファを作成していないとし、XなどのIDE、Visual Studioで、コモド、およびVisual SlickEditは、開発する特殊なタグコードを記述されていませんか理解していない。 記事は、ソニアLandeを提出 免責事項:弊社のウェブサイトは、この資料の内容については責任を負いません。 Webarticles無料の情報リソースです。 重要: この記事は、""JavaScriptのジェネリックの実装の自動ソフトウェアによって翻訳された。大変申し訳ございませんが発生した可能性があります任意のスペルミスを感じている。お客様のご理解いただき、ありがとうございます。
|
|||||
| Online: 152 users browsing the articles directory |
|
|