ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript で関数のオーバーロードを簡単にサポートできるようにする (パート 2 - 実装)_JavaScript スキル

JavaScript で関数のオーバーロードを簡単にサポートできるようにする (パート 2 - 実装)_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 18:48:36959ブラウズ
テキスト署名の認識
まず、前の記事で説明したオーバーロードの使用例を確認してみましょう:

コードをコピー コードは次のとおりです。

var extend = Overload
.add("*, ...",
function(target) { })
.add("Boolean, *, ...",
function(deep, target) { });


ユーザーが特定のキーを表す文字列を入力できるようにします署名が入っていました。ユーザーが関数を呼び出すとき、ユーザーが入力したパラメーター インスタンスをシグネチャ内の各パラメーターの型と比較する必要があるため、最初に文字列を型配列に変換する必要があります。つまり、文字列「Boolean, Number, Array」は配列 [Boolean, Number, Array] に変換される必要があります。

変換する前に、まず 2 つの特殊な型、つまり任意の型を表す "*" と任意の数値を表す "..." の処理を​​考慮する必要があります。オーバーロード内で特別な互換性処理を行うために、2 つの独自の型を定義できます:

コードをコピー コードは次のとおりです。

Overload.Any = function() {};
Overload.More = function() {};


2 つのタイプの場合、文字列「Boolean, *, ...」は配列 [Boolean, Overload.Any, Overload.More] に正しく変換されます。 Overload.Any と Overload.More はどちらも関数であるため、当然ながら型とみなすことができます。

これら 2 つの型が正しく処理されたら、テキスト署名を認識する変換関数の記述を開始できます:

コードをコピー コードは次のとおりです。

if (signature.replace(/(^s |s $)/ig, "") == "") {
signature = [];
} else {
signature = signal.split(",");
for (var i = 0; i
var typeExpression = signature[i].replace(/(^s |s $)/ig, "");
var type = null;
if (typeExpression == "*") {
type = オーバーロード。 Any;
} else if (typeExpression == "...") {
type = Overload.More;
} else {
type = eval("(" typeExpression ")");
}
signature[i] = type;
}
}

このコードは非常に理解しやすいと思うので、これ以上は説明しません。最初にこのコードを書いたとき、上記の最初の if を書き忘れました。その結果、空の署名文字列 "" が空の署名配列 [] として正しく認識されませんでした。幸いなことに、私の単体テスト コードはこの欠陥をすぐに発見しました。 。単体テストコードを書くことは依然として非常に重要なようです。

関数シグネチャの一致
関数シグネチャの型配列を取得したら、それを使用して入力パラメータのインスタンス配列と一致させ、正しい繰り返し負荷を見つけることができます。関数のシグネチャを一致させる方法について説明する前に、まず C# や VB.NET などの言語が関数のオーバーロードの一致をどのように処理するかを見てみましょう。一般言語における関数オーバーロードのマッチングのプロセスは次のとおりです。

パラメータの数 - パラメータの数が正しくないオーバーロードは除外されます。
パラメータの型 - パラメータの型は暗黙的にシグネチャに変換できません。除外される
一致の数 - 除外後、残りの一致する署名の数は別の方法で処理されます
0 一致 - ヒットなし
1 一致 - これはヒットです 一致
2 つ以上の一致 -これらの一致の中で最良の一致が見つかった場合は、最も一致したものがヒットします。そうでない場合は、一致はヒットしません。
このセクションでは、最初にプロセスを扱います。 最初の 2 つのステップでは、一貫性のないパラメータ番号またはパラメータを持つ署名を削除します。タイプ:

コードをコピー コードは次のとおりです:

var matchSignature = function (argumentsArray, signed) {
if (argumentsArray.length return false;
} else if (argumentsArray.length >signature.length && !signature.more) {
return false;
}
for (var i = 0; i if (!(signature[i] == Overload.Any
||引数配列[i] 署名のインスタンス[i]
|| 引数Array[i].constructor == 署名[i])) {
return
}
}
return
};

長さを比較するには、この関数の外側に任意の数のパラメータを示す「...」を追加する必要があります:

コードをコピーします コードは次のとおりです:

if (signature[signature.length - 1] == オーバーロード.More) {
signature.length = signal.length - 1;
signature.more = true; 🎜>

このコード部分は、最初のセクションの変換関数の最後に統合されるため、matchSignature 関数はパラメーターと署名が一致するかどうかを簡単に判断できます。最も理想的なケースでは、入力パラメーターの型に対して 0 または 1 のオーバーロードが一致するため、どのオーバーロードがヒットしたかを簡単に判断できます。ただし、オーバーロードの一致が 2 つ以上ある場合は、最適なものを選択する必要があります。これについては次のセクションで説明します。


複数の一致の処理
C# が複数の一致からさらに一致するオーバーロードを選択する方法については、C# 言語仕様の関連する章を参照してください。この問題は 3 つの簡単な例で説明できると思います。


long Sum(int x, int y) { return x y; }
long Sum(long x, long y) { return x y; }
Sum(0, 1); >

2 つのパラメーター 0 と 1 はコンパイラーによって int 型として認識されるため、最初のオーバーロードでは型変換する必要はなく、2 番目のオーバーロードでは型変換する必要があります。最初のオーバーロードの方が良いです。




コードをコピー
コードは次のとおりです。long Sum(int x, long y) { return x y; } long Sum(long x, int y) { return x y; }


パラメータの場合は最初のオーバーロードの方が優れており、2 番目のパラメータの場合は 2 番目のオーバーロードの方が優れています。この場合、どのオーバーロードも他のオーバーロードより優れているわけではないため、より優れたオーバーロードが見つからない場合、コンパイラーはエラーを報告します。




コードをコピー
コードは次のとおりです。long Sum(int x, int y) { return x y; } long Sum(int x, long y) { return x y; } long Sum(long x, int y) { return x y; } );


最初のパラメーターでは、最初のオーバーロードは 3 番目のオーバーロードよりも優れており、2 番目のパラメーターでは最初のオーバーロードの方が優れています。 2 回目の過負荷ですが、3 回目の過負荷と変わりません。 2 番目のオーバーロードは 3 番目のオーバーロードと区別できませんが、最初のオーバーロードがすべてのオーバーロードよりも優れていることは確実なので、コンパイラは最初のオーバーロードを選択しました。

任意の 2 つのシグネチャの長所と短所を比較できる overloadComparator の比較関数があるとします。最適なオーバーロードを見つけるには、シグニチャをペアごとにのみ比較する必要があるのでしょうか。実際、これは必要ありません。Array の sort メソッドを使用して、並べ替えのために overloadComparator を呼び出すことができます。上位 2 つの関係が一致している場合は、どちらもヒットしません。優先順位が の場合、最初のものがヒットします。
ここでは、具体的な overloadComparator コードは示しません。これは、inheritanceComparator と呼ばれる別の比較関数に依存して、渡された実際のパラメーターの型に近い方の 2 つのシグネチャのパラメーターの型を比較します。 2 つの型に継承関係があるかどうか、また誰が誰から継承するかを判断する賢い方法です。


概要

これで、JavaScript 関数のオーバーロード ライブラリが完成しました。完全なコードについては、「関数のオーバーロード ライブラリのオーバーロード」を参照してください。このライブラリが、誰もが JavaScript コードの可読性を向上させ、大規模な Ajax プロジェクトのメンテナンス コストを削減するのに効果的に役立つことを願っています。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。