メソッドのオーバーロードをしてみる
JavaScriptでは、関数の引数の型や個数をチェックしないため、いわゆるメソッドのオーバーロードをすることはできない。(というのはどこかで書いた気がする⇒「関数のオーバーロードはできないよ - HHeLiBeXの日記 正道編」)
// !!!世の中、思い通りにはいかないよ!!! function Hoge() { } Hoge.prototype.fuga = function(str) { return 'string: ' + str; } Hoge.prototype.fuga = function(str1, str2) { return 'two strings: ' + str1 + ' and ' + str2; } alert(new Hoge().fuga('Hello')); // 'two strings: Hello and undefined'
この程度の処理なら、ひとつのメソッドの中で引数のチェックをすればよいのだが、規模が大きくなるとわけ分からなくなりそう。
ということで、ちょっともがいてみた(謎)。
- Hoge.js
// コンストラクタ。とりあえずやることはなし。 function Hoge() { } // public な fuga メソッド。引数に応じて適切なメソッド実体へ委譲。 Hoge.prototype.fuga = function() { if (arguments.length != 1) { throw { name: 'AssertionError', message: 'exactly one argument is required.' }; } if (typeof arguments[0] === 'number') { return this.privateMethods['_fuga_number'](arguments[0]); } else if (typeof arguments[0] === 'string') { return this.privateMethods['_fuga_string'](arguments[0]); } else { throw { name: 'AssertionError', message: 'invalid argument ' + arguments[0] + ' (' + (typeof arguments[0]) + ')' }; } } // オーバーロードするメソッドの実体 Hoge.prototype.privateMethods = Array(); // Hoge.fuga(number) Hoge.prototype.privateMethods['_fuga_number'] = function(num) { return 'number: ' + num + ' (' + (typeof num) + ')'; } // Hoge.fuga(string) Hoge.prototype.privateMethods['_fuga_string'] = function(str) { return 'string: ' + str + ' (' + (typeof str) + ')'; }
- test.html
<html> <head> <title>overload test</title> <script type="text/javascript" src="Hoge.js"></script> <script type="text/javascript"> function Foo() { } function test(arg) { var hoge = new Hoge(); try { alert(hoge.fuga(arg)); } catch (e) { alert(e.name + ': ' + e.message); } } </script> </head> <body> <input type="button" onclick="javascript:test(1)" value="「1」" /> <input type="button" onclick="javascript:test('1')" value="「'1'」" /> <input type="button" onclick="javascript:test(new Foo())" value="「new Foo()」" /> <input type="button" onclick="javascript:test(null)" value="「null」" /> <input type="button" onclick="javascript:test(false)" value="「false」" /> <input type="button" onclick="javascript:test(true)" value="「true」" /> </body> </html>
これでnumberなのかstringなのかを気にせずに同じメソッド名で呼び出せる。
まぁ、これが「JavaScript: The Good Parts」的にいいのか悪いのかは知らないけど(ぉ
JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
- 作者: Douglas Crockford,水野貴明
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/12/22
- メディア: 大型本
- 購入: 94人 クリック: 1,643回
- この商品を含むブログ (187件) を見る