1

私は自分のレベルより少し上の本を読んでいます。この本の著者は、匿名関数を使用してプライベート スコープを作成する方法を示しています。プライベート スコープの概念は理解できますが、それがどのように達成されるのかわかりません。これらのローカル変数は現在のスコープでのみアクセスできることはわかっていますが(著者の言葉です)、どのように呼び出されて実装されるのかわかりません。var Tim = new Person();以下を使用して実際のコードでどのように使用されるかについての例を教えてください

匿名関数を使用してプライベート スコープを作成する:

var Person = function(){};

(function(){
  var findById = function(){ /* ... */ };
  Person.find = function(id){
    if (typeof id == "integer")
      return findById(id);
   };
})();

私の理解

var Tim = new Person(); 

私は何と呼びますか?ティムの ID を見つけようとしますか?

4

2 に答える 2

3

まず第一に、あなたが提供したスニペットは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、モバイルデバイスでイベントの独自の委任を作成してみてください)。それらをグーグルで検索すると、なぜそれが良い運動であるかがすぐにわかりますが、最初は少し気が遠くなります。

于 2012-09-11T20:27:44.093 に答える
0

findById次のように呼び出すことで、間接的にのみ呼び出すことができますPerson.find

// Assuming code similar to your code above
// Assume that Tim.id === 1
var someone = Person.find(1); // Call findById to get a reference to Tim
console.log(someone.name); // Tim
findById(1) // Error, findById is not available in the global scope
于 2012-09-11T20:11:58.950 に答える