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

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

WBOY
WBOYオリジナル
2016-05-16 18:48:38935ブラウズ
JavaScript はオーバーロードをサポートしていますか?
JavaScript は関数のオーバーロードをサポートしていますか?支持しないとも言えますし、支持するとも言えます。関数のオーバーロードをネイティブにサポートする他の言語のように、JavaScript は同じ名前の複数の関数を直接記述して、特定の呼び出しにどのオーバーロードが対応するかをコンパイラーに判断させることができないため、サポートされていないと言われています。これは、JavaScript 関数がパラメーター リストに制限を課しておらず、関数のオーバーロードのサポートを関数内でシミュレートできるためサポートされていると言われています。
実際、多くのよく知られたオープン ソース ライブラリでは、関数内で内部シミュレーション オーバーロード サポートの設計が見られます。たとえば、jQuery の jQuery.extend メソッドは、パラメータの型によってオプションのパラメータが存在するかどうかを判断し、存在しない場合は、後続のロジックが正しく実行されるようにパラメータがシフトされます。 JavaScript を記述するときに、機能豊富な関数に単純な呼び出しエントリ (または複数) を提供するために、多くの人が同様のコードを書いたことがあると思います。
しかし、この播種方法には根本的な問題があります。それは、DRY 原則に違反しているということです。オーバーロードをサポートする各関数には、内部に追加のコードがあり、パラメーターの数とパラメーターの型に基づいてオーバーロードを処理するために使用されます。これらのコードは繰り返しロジックを意味しますが、各コードは作成時に異なります。さらに、これらのコードは保守が容易ではありません。コードを読んだときに、その関数でサポートされているいくつかのオーバーロード メソッドが何であるか一目ではわかりません。また、当然のことながらオーバーロードの保守も困難です。
オーバーロードされたポータルを記述する DSL
JavaScript で簡単な方法でオーバーロードされたポータルを記述できるようにしたいと考えています。他の言語と同様に、オーバーロード エントリを区別するには関数シグネチャを使用するのが最善です。これには関数シグネチャが最適な DSL だと思うからです。 JavaScript 構文と最も一致すると私が想像するオーバーロードされたエントリ記述 DSL は次のようになります。
コードをコピー コードは次のとおりです。 :

var sum = new Overload();
sum.add("Number, Number",
function(x, y) { return x y; }); sum.add ("Number, Number, Number",
function(x, y, z) { return x y z; });

オーバーロードされたエントリと対応する関数本体を記述した後、sum関数呼び出しは次のようになります。
sum(1, 2);
sum(1, 2, 3);
上記のコードは非常にわかりやすく、保守しやすいように思えます。リロード エントリの署名が一目でわかるため、リロード エントリの変更や追加が非常に簡単です。しかし、問題が発生しました。つまり、JavaScript の関数は new にすることができず、new Overload() を通じて取得したオブジェクトを呼び出すことはできません。このため、Overload を静的クラスにすることしかできず、静的メソッドは Function インスタンスを返します。

コードをコピー コードは次のとおりです:
var sum = Overload
.add ("数値, 数値",
function(x, y) { return x y; })
.add("数値, 数値, 数値",
function(x, y, z) { return x y z ; });

必要なオーバーロードされたエントリのサポート
上記の DSL で記述できない一般的な JavaScript 関数のエントリを想像してみてください。私が知っているタイプは 2 つあります:
任意の型パラメーター
配列の場合はその添え字を反復し、他の型の場合はそのすべてのメンバーの入り口を反復します。 2 つの関数は次のとおりです: パラメーター リストを宣言するにはどうすればよいですか? C# を使用する場合、2 つの関数の入口を次のように記述します。
void Each(IEnumerable iterator) { }
void Each(object iterator) { }
ただし、JavaScript では、Object は基本クラスではありません。すべての型の , (100)instanceof Object の結果は false であるため、Object を使用して型を参照することはできず、型を参照するには新しいシンボルを導入する必要があります。この記号が考えられるクラス名と競合してはならないことを考慮して、任意の型を表すために「*」を使用することにしました。上記の C# コードに対応する JavaScript は次のようになります:

コードをコピーします コードは次のとおりです:
var each = オーバーロード
.add("Array",
function(array) { })
.add("*",
function(object) { });


任意の数のパラメータ JavaScript 関数では、任意の数のパラメータをサポートすることが非常に一般的な要件であり、params キーワードよりもはるかに多く使用されていると思います。 C#で。これは以前に策定したルールでは記述できないため、C# で params を表現するにはクラス名と矛盾しないシンボルを導入する必要があります。パラメータを表すために「...」を使用することにしました。これは、ここに存在するパラメータの数に制限がないことを意味します。 jQuery.extend のオーバーロードをどのように記述すべきかを見てみましょう:

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

var extend = オーバーロード
.add("*, ...",
function(target) { })
.add("Boolean, *, ...",
function(deep, target) { });

概要
この記事では、JavaScript に適した、簡単に実行できるメソッドの設計を試みます。保守が容易な関数のオーバーロード。次の記事では、この設計を実装するための Overload クラスを作成してみます。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。