プロパティと継承 JavaScriptの個人的なメモ (その5)
このメモについて
このメモは他の言語を習得している人用に向けて、それらとJavaScriptの違いを書いています。
誤りがあれば直しますので、ご指摘ください。
前回のメモ - プロトタイプ - JavaScriptの個人的なメモ (その4)
プロパティの継承
プロパティは、インスタンス変数でもなければ、メンバでもありません。それらの代用はできます。見かけ上は同じです。
しかし、常に継承が働いているため、メソッドと同等です。このことを理解するために、次のコードを見てください。
var obj = {}; /*オブジェクトを作る*/ Object.prototype.x; /* undefined */ obj.x; /* undefined */ Object.prototype.x = 12; obj.x; /* 12 */ Object.prototype.x = 0; obj.x; /* 0 */
オブジェクトobjのxプロパティの値は、常にObject.prototype.xと連動しています。これはプロトタイプチェーンをたどって、Object.prototypeまでさかのぼり、プロパティの値を参照しているからです。ただし、obj.xを直接、書き換えると、連動しなくなります。メソッドのオーバライドと同様です。
obj.x = 12; Object.prototype.x = 25; obj.x; /* 12 */
このように、プロパティには継承機能があって、代入がない限り、いつもプロトタイプを参照しようとします。ですから、プロパティには初期化が必要となります。
プロパティの初期化
プロパティの初期化には、オブジェクトリテラルや関数を使う方法があります。どの方法も、値を入れるだけです。
パフォーマンス上の理由から、以下の二つの方式が用いられることが多いです。
var obj = { x : 12 }, F = function() { this.x = 12; }, ob = new F(); obj.x; /* 12 */ ob.x; /* 12 */
親オブジェクトから継承する
プロトタイプを使って、親オブジェクトからプロパティを継承してみましょう。
/*コンストラクタ関数用のメソッド*/ Function.prototype.create = function(o) { this.prototype = o || {}; return new this(); }; var A = function() { this.n = 12; }, B = function(){ this.m = 1; }, /*それぞれプロトタイプを設定してオブジェクトを作成*/ a = A.create(), b = B.create(a), c = B.create(b); a.n; /* 12 を返す*/ b.n; /* 12 を返す*/ c.n; /* 12 を返す*/
結論
- プロパティは親オブジェクトから継承します
- 前もって設定しておかないと、Object.prototypeなど、コンストラクタ関数.prototypeの影響を受けます