var inner = new Inner() 行は、inner が定義されていないためエラーをスローします。Outer 関数の本体内でのみアクセスできます。
inner.private はクロージャ変数であるため、inner のプロパティとしてアクセスできません。したがって、 (new Inner()).private は存在しません。(private は JS のキーワードらしいので、サンプルコードでは priv に変更しています)
関数本体内のコードはクロージャー変数への参照を保持するため、内部関数本体内でアクセスできます。
function Inner(){
var priv="something";
this.method = function(){//wrong, should declare as prototype
console.log("private from within Inner function body:"
,priv)
};
}
var inner = new Inner();
console.log(inner.priv); //=undefined
inner.method();//=something
多くのインスタンスを持つオブジェクトの関数プロパティ。like Inner は次のような多くのインスタンスを持つことができます: var a=new Inner(); var b = new Inner()... これで定義しないでください。代わりにプロトタイプを使用する必要があります。
プロトタイプを使用する場合、プライベート (クロージャー) 変数はメイン関数本体内でしかアクセスできないため、プロトタイプ関数でプライベート変数を使用することはできません。JavaScript には、プロトタイプを台無しにすることなくメンバーを非公開にする良い方法がないため、多くの開発者が非公開であることを示すために_private
orを使用するのはこのためです。private_
function Inner(){
var priv="private";//wrong
this._priv="private"
}
Inner.prototype.method=function(){
//cannot access priv
console.log(this._priv);//no problem
}
このようにプライベートを使用できるケースがおそらく 1 つあります。それは、オブジェクトのインスタンスが 1 つしかない場合です。
var Mediator=(function(){
var events={};//private, other code can't mess this up
return{
addEvent:function(eventName){
events[eventName]=(events[eventName])?
events[eventName]:[];
},
addLisener:function(eventName,func){
events[eventName].push(func);
return events[eventName].length-1;
}
//more stuff like removeListener, trigger ...
}
})()
プロトタイプについては、この基本的な例を参照してください。Firebug コンソールを使用して、Chrome または Firefox でコードを実行できます。F12 キーを押して開き、そのリンクからコードをコンソールに貼り付けます。次に、好きなようにいじって、期待どおりの出力が得られ、JS でのプロトタイピングを理解できるかどうかを確認します。