Javaのextendsにあたる明示的な継承手段をJavaScriptは提供していない。ただ実質的に継承に相当する機能を実現する方法がいくつかある。
継承先のオブジェクトのprototypeプロパティに継承元のインスタンスを設定する。
/* * 親 : Family * 子 : Self */ var Family = function () { this.familyName = '山田'; } Family.prototype.getFamilyName = function () { return this.familyName; } var Self = function (value) { this.name = value; } // 継承 Self.prototype = new Family(); // Self.prototype = Family; ではダメ-----(1) Self.prototype.getName = function () { return this.familyName + ' ' + this.name; } // インスタンスを作成 var my = new Self("太郎"); my.getName(); // 山田 太郎
prototypeにnew演算子で生成したインスタンスを設定する。
コンストラクタ(関数オブジェクト)を直接設定してもthisを参照できな点に注意する
一般にコンストラクタ(関数オブジェクト)から生成したインスタンス[1]は暗黙リンク[2]にコンストラクタ(関数オブジェクト)のprototypeプロパティが設定される。
継承を実現するには子インスタンスが親関数オブジェクトのprototypeプロパティを参照できればよい。
基本的には次のような方法で継承を実現することができる。
/* * 親 : ParentObject * 子 : ChildObject */ /* * 親 : ParentObject * 子 : ChildObject */ var ParentObject = function(value) { this.name = value; }; ParentObject.prototype.family = '山田'; ParentObject.prototype.showFullName = function() { return this.family + ' ' + this.name; }; var ChildObject = function(name, gender) { // thisプロパティを継承 ParentObject.apply(this, [name]); // ChildObject固有のプロパティ this.gender = gender; }; // prototypeプロパティを継承 for (var prop in ParentObject.prototype) { ChildObject.prototype[prop] = ParentObject.prototype[prop]; }; // 継承先のインスタンスを作成 var child = new ChildObject('小太郎', '男'); // 実行画面 アラートボックス alert(child.showFullName() + ' : ' + child.gender); // 山田 小太郎 : 男
Functionオブジェクトのapplyメソッドについては下記サイトに詳しい説明がある。
» JavaScriptのapplyヤバい – ++iskwn – キューイチ世代
『JavaScript: The Good Parts』 (pp59-63)はnew演算子を使わない継承方法を紹介している。
var integer = function (spec, my) { var that = {}; // パブリック var my = my || {}; // プライベート // パブリック that.getValue = function () { return spec.value; } return that; } var interger2Times = function (spec) { var that = integer(spec); that.getTimes = function () { return spec.value * 2; } return that; } var o = interger2Times({value: 3}); o.getValue(); // 実行結果 3 o.getTimes(); // 実行結果 6
Douglas Crockford著 水野 貴明訳 2008 『JavaScript: The Good Parts』 オライリー・ジャパン
プライベートメンバを設定した場合の例
var circle = function (spec, my) { var that = {}; // インスタンス var my = my || {}; // プライベート if ( my.pi == undefined ) { my.pi = 3; } // パブリックメンバ that.getArea = function () { return my.pi * spec.radius * spec.radius; } return that; } var strictCircle = function (spec, my) { var that = circle(spec, my); that.getCircumference = function () { return 2 * my.pi * spec.radius; } return that; } var o = strictCircle({radius: 3}, {pi: 3.14}); o.getAarea(); // 28.25999999… o.getCircumference(); // 18.84
1. new演算子使ってインスタンスの生成に使われた関数オブジェクトをコンストラクタと呼ぶ。
2. 処理系によっては暗黙リンクを__proto__プロパティとして公開している。
3. applay関数については下記を参照。
» apply, call : JavaScript
No comments yet.
改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。