まず第一に、あなたが提供したスニペットはIDを返しませんが、IDが渡されると何かを返します。プライベートスコープに関しては、この例が最良の例ではないことを認めなければなりません。もっと詳しく説明しますが、より明確な例を示します。
(function ()
{
var personObjects = [];
var findById = function(id)
{
return personObjects[id];
}
var Person = function (name)
{
this.id = personObjects.length;//first available index ~= auto increment
this.name = name;
personObjects.push(this);
};
Person.find = function(id)
{
//I woudl do: id = +id;, but sticking to your example
if (typeof id === 'number')
{
return findById(id);
}
return undefined;
}
window.Person = Person;//expose to global object
})();
それで、ここには何がありますか。スコープについて理解していると言うので、ここで宣言されたすべての変数はラッパー関数が戻った後も存続することを知っていると思いますが、それらは同じスコープで宣言された関数にのみ表示されます。そうでない場合:personObjects
配列と関数オブジェクトはまだ存在しますが、グローバルオブジェクトが公開されている(割り当てられているため)コンストラクターfindById
によってのみアクセスできます。Person
配列の長さを使用して、人物オブジェクトがインスタンス化されるたびに次に使用可能なIDを決定し、すべてのオブジェクトに一意のIDを作成しています。関数findByIdは、有効なID(配列キー)をオブジェクトに渡すと、オブジェクトの1つへの参照を返すだけです。このPerson.find
メソッドはこの囲まれた関数を呼び出しますが、そうする前に引数をチェックします。これは、いくつかの非常に特殊なケースでは、デバッグ、または長いプロトタイプチェーンでのジェネリックセッターとゲッターの使用に役立つ可能性があります。そのため、少なくとも私にとっては、この例は出発点として少し遠いところにあります。
とにかく、あなたはこのプライベートメソッド(findById
)を次のように呼び出します:
var tim = new Person('tim');
Person.find(0);// returns a reference to tim
//or even
var tom = new Person('Tom');
tim.find(1);//returns tom
tom.find(0);//returns tim
tim.find(tom.id);//...
繰り返しになりますが、このアプローチはあまり一般的ではありません。スコープとクロージャを練習/慣れるにはsetInterval
、イベントの委任を使って魔法を使うことをお勧めします(たとえばtab
、モバイルデバイスでイベントの独自の委任を作成してみてください)。それらをグーグルで検索すると、なぜそれが良い運動であるかがすぐにわかりますが、最初は少し気が遠くなります。