読者です 読者をやめる 読者になる 読者になる

野次馬エンジニア道

野次馬な気持ちでプログラミングをあれこれと綴ります

JavaScriptでオブジェクト指向 (3) - プロパティとアクセス制御

前回は継承を調べた。

プロパティ

オブジェクトを定義したときは何らかのプロパティを定義することがほとんど。 どこに定義するかで、クラス経由かインスタンス経由でアクセスできるかが変わる。

function Foo(){}
var bar = new Foo();
Foo.val = 'something'; // 静的プロパティ
Foo.prototype.val = 'something'; // インスタンスプロパティ 
bar.val;

関数も同様。実際にコーディングするときは、

function Foo() {
  this.val = 'something';
}

と書いた方が伝わりやすいかもしれない。

プロパティのコピーによる継承

前回登場した継承のユーティリティ関数を プロパティのコピーでも実装すると

function extend( SubClass,  BaseClass ) {
 var p = BaseClass.prototype;
 var c = SubClass.prototype;
 for ( var i in p ) {
  c[i] = p[i];
 }
}

となる。プロトタイプチェーンを辿らずとも、コピーしているので自分のプロパティとして見える。 このとき配列や関数は参照がコピーされることに注意。

プライベート変数

JavaScriptにはprivateといった修飾子は無い。代わりにクロージャーを使った方法。

function Foo() {
 var _val;
 this.getValue = function() {
  return _val;
 }
}

prototypeにメンバ変数としてプロパティを追加した場合、インスタンス毎には変数は作成されない。 一方で、コンストラクタに押し込めると、インスタンスの生成毎にメモリを消費する。

プライベート関数

プロパティを介して、アクセスできる関数を制御する方法。

function Foo () {
 var _val;
 function _getValue(){
   return _val;
 } 
 return { getValue : _getValue };
}

他人のソースでprivateにしたいという意図を汲み取るために上記のパターンは知るべき。アクセス制御をせずに実装し、変数名の先頭にに_(アンダースコア)をつけることでprivateとして扱う運用も現実的なアプローチ。