1時間の余裕があったので、「フアンメンデス」と「システム」の両方から受け取ったさまざまな提案を実装してみようと思いました。
以下は単なる実用的な例です(最適化されていない、ベンチマークされていない、クリーンアップされていない)ので、進行中と考えてください。他のことをする前に、いくつかのベンチマークを実行して、最終的にどのような「肥大化」が発生するかを確認したいと思います。
誰かがこれに何か問題があると思ったら、建設的な批判をしてください!
function Overload() {
// Empty for now!
}
Overload.prototype.link = function (object, method) {
console.log("Creating dispatch method '" + method + "()'");
object.prototype[method] = function () {
var target = method + "_";
console.log("Invoked dispatch method '" + method + "()'...");
for (var i=0; i < arguments.length; i++) {
target += (typeof arguments[i]).substring(0, 1);
}
console.log("Resolved target as '" + target + "'");
if (typeof object.prototype._overloaded[target] !== "undefined") {
console.log("Dispatching to overloaded method: '" + target + "'");
return object.prototype._overloaded[target].apply(object, arguments);
} else {
console.log("Method not found: '" + method + "('" + target + "')'");
//throw "Exception ...";
}
}
}
次の関数は、オブジェクト上の他のすべての関数をオーバーロードするために使用されます。
Overload.prototype.overload = function (object, method, fn, params) {
var target = method + "_" + params;
console.log("Overloading method '" + method + "()' to '" + method + "('" + params + "')'");
if (typeof object === "undefined") {
console.log("Object doesn't exist!");
}
if (typeof object.prototype[method] === "undefined") {
this.link(object, method);
}
if (typeof object.prototype._overloaded === "undefined") {
console.log("Creating '[obj].prototype._overloaded' property");
object.prototype._overloaded = {};
}
if (typeof object.prototype._overloaded[target] === "undefined") {
//console.log("Assigning overload function as target '" + method + "('" + params + "')'");
object.prototype._overloaded[target] = fn;
} else {
console.log("Definition for '" + method + "('" + params + "')' already eixsts!");
}
return fn;
}
次に、オーバーロードされた関数を本質的に「モック」するいくつかのサンプル関数を定義します。
function fn1(one) {
console.log("Invoked function 1: " + one);
}
function fn2(one, two) {
console.log("Invoked function 2: " + one + ", " + two);
}
function fn3(one, two, three) {
console.log("Invoked function 3: " + one + ", " + two + ", " + three);
}
function fn4(one, two, three) {
console.log("Invoked function 4: " + one + ", " + two);
}
function fn5(one, two, three) {
console.log("Invoked function 5: " + one + ", " + two);
}
これを使用してテストを実行します。
function testMethodOverloading() {
console.log("Testing method overloading!");
var ov = new Overload();
function OBJ() {}
console.log("--");
ov.overload(OBJ, "name", fn1, 's');
ov.overload(OBJ, "name", fn2, 'sn');
ov.overload(OBJ, "name", fn3, 'sns');
ov.overload(OBJ, "name", fn4, 'ss');
ov.overload(OBJ, "name", fn5, 'nn');
console.log("--");
var obj = new OBJ();
obj.name("one");
obj.name("two", 1);
obj.name("three", 2, "four");
obj.name("five", "six");
obj.name(3, 4);
}
これは、上記のテストを実行して得た出力です。
Overloading method 'name()' to 'name('s')'
Creating dispatch method 'name()'
Creating '[obj].prototype._overloaded' property
Overloading method 'name()' to 'name('sn')'
Overloading method 'name()' to 'name('sns')'
Overloading method 'name()' to 'name('ss')'
Overloading method 'name()' to 'name('nn')'
--
Invoked dispatch method 'name()'...
Resolved target as 'name_s'
Dispatching to overloaded method: 'name_s'
Invoked function 1: one
Invoked dispatch method 'name()'...
Resolved target as 'name_sn'
Dispatching to overloaded method: 'name_sn'
Invoked function 2: two, 1
Invoked dispatch method 'name()'...
Resolved target as 'name_sns'
Dispatching to overloaded method: 'name_sns'
Invoked function 3: three, 2, four
Invoked dispatch method 'name()'...
Resolved target as 'name_ss'
Dispatching to overloaded method: 'name_ss'
Invoked function 4: five, six
Invoked dispatch method 'name()'...
Resolved target as 'name_nn'
Dispatching to overloaded method: 'name_nn'
Invoked function 5: 3, 4
だから、私が期待した/望んでいたようにそれは間違いなく実行されます!しかし、どのようなベンチマークが得られるのでしょうか。次に、参照されている記事のベンチマークの範囲内にいるかどうかを確認するためにそれを実行します(つまり、すべてのログを削除した後)。一般的な考え方がわかったら、結果を投稿します。