1

次のコードを検討してください。

function Outer(){
  function Inner(){
    var private="something";
    this.method = function(){    
     //some code here    
   };
  }

 var inner = new Inner(); //Why does this line not throw an error?
 alert(inner.private); // not accessible here
 inner.method();//no errors here
}

method() 呼び出しがエラーをスローせず、変数参照がエラーをスローする理由を理解できませんか? 変数の有効範囲は、変数が宣言されている関数内のみであることを理解していますか? しかし、関数の範囲はどうですか?

4

2 に答える 2

3

複雑なことは何もなく、データ型とは何の関係もありません。

new Inner()新しいオブジェクトを作成します。コンストラクターでそのオブジェクトにプロパティを割り当てています

this.method = function(){...};

一方、そのようなプロパティはありませんprivate。あなたは決してしませんthis.private = ...;private関数にローカルな単なる変数ですInner

これはあなたのコードと同等ですが、うまくいけばより明確になる別の例です:

function createObject() {
    var someVariable = '42';
    var obj  = {};
    obj.foo = 'bar';
    return obj;
}

var myObject = createObject();
// works, since we assigned the property to the object
console.log(myObject.foo); 
// does not work, we never assigned such a property to the object
console.log(myObject.someVariable); 

内部createObjectでは 2 つの変数が宣言されておりsomeVariableobj. objがオブジェクトの場合、それにプロパティを割り当て、関数から返します。someVariableオブジェクトとは関係ありませんが、関数内で他の目的に使用できます。

于 2013-06-02T12:53:53.327 に答える
1

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 には、プロトタイプを台無しにすることなくメンバーを非公開にする良い方法がないため、多くの開発者が非公開であることを示すために_privateorを使用するのはこのためです。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 でのプロトタイピングを理解できるかどうかを確認します。

于 2013-06-02T12:54:01.643 に答える