JavaScriptにおける関数型コンストラクタ
どうもこんばんは、south37です。前回の続きとして、jsにおける「関数型コンストラクタ」とはなんぞや、ってところから書き始めたいと思います。参考にしてるのはやっぱりJavaScript-The-Good-Partsです。
関数型コンストラクタ
関数型コンストラクタは、簡単にいえばオブジェクトを返す関数です。jsのnewがあまりにもクソだから極力使いたくなくて、代わりに関数型コンストラクタを使おうって事らしいです。まずは概念をコードで示してみます。
var constructor = function (spec) { var that; その他のインスタンスプライベート変数もここで宣言 that = 新しいオブジェクト; メソッドをthatに追加 return that; }
仕組みは単純で、thatオブジェクトを生成した後、メソッドを追加してからreturnするだけです。注目すべきは、メソッドを追加する際にクロージャを利用して変数のカプセル化を行っている事でしょうか。これにより、擬似的なプライベート変数を作る事が出来ます。これが最大のメリットと言えます。
ちなみに、コンストラクタの引数のspecは「仕様(specification)」という意味で、オブジェクト初期化に必要な情報をためこんだコンテナです。
関数型コンストラクタを用いた具体的な例を示してみます。
var mammal = function (spec) { var that = {}, name = spec.name, saying = spec.saying; that.get_name = function () { return name; }; that.says = function () { return saying; }; return that; }; var myMammal = mammal({ name: 'Herb', saying: 'meow' }); console.log(myMammal.name); //undefined console.log(myMammal.get_name()); //Herb
myMammalのnameがカプセル化されているのが分かるかと思います。
superiorメソッド
関数型コンストラクタを用いる際、、Objectクラスのprototypeを拡張してsuperiorメソッドというものを定義する事で、継承元のメソッドの呼び出しも行えるようになります。
Object.method('superior', function (name) { var that = this, method = that[name]; return function () { return method.apply(that, arguments); }; }); var mammalBaby = function (spec) { var that = mammal(spec), super_get_name = that.superior('get_name'); that.get_name = function () { return 'like ' + super_get_name() + ' baby'; }; return that; } var myMammalBaby = mammalBaby({ name: 'Herb', saying: 'meow' }); console.log(myMammalBaby.get_name()); //like Herb baby
継承元のmammalに存在したget_nameを利用しながら、get_nameを上書きしています。ポイントは、super_get_nameという名前をつけて継承元のget_nameへの参照を残している点です。クロージャを上手く利用しているといえます。
今日はここまでです!