2012-05-23 9 views
13

私は、このクラスを持っているJavaScriptのプライベート機能アクセスパブリック変数

function ctest() { 
    this.var1 = "haha"; 
    this.func1 = function() { 
     alert(this.var1); 
     func2(); 
     alert(this.var1); 
    } 
    var func2 = function() { 
     this.var1 = "huhu"; 
    } 
} 

とそれを呼び出す:

var myobj = new ctest(); 
    myobj.func1(); 

は、第二警告は "HUHU" をポップアップ表示することが想定されていませんか? func2はプライベートなので、var1 public変数にアクセスできませんか?

プライベート関数がパブリック変数にアクセスできない場合はどうすればいいですか?

ありがとうございます!

+2

また、ここに「プライベート」のようなものはありません。 – Alexander

+0

この 'obj.func1()' 'おそらくmyobj.func1(あるべき)' – forsvarir

+0

は@forsvarirええ、それがなければならない - 私は彼のためにそれを修正。 – Alnitak

答えて

17

あなたはfunc2への呼び出しのためのコンテキストを提供する必要があります:呼び出しはグローバルオブジェクト(すなわちwindow)を使用する文脈がないと

this.func1 = function() { 
    alert(this.var1); 
    func2.call(this); 
    alert(this.var1); 
} 

- あなたはwindow.var1であることを、あなたの現在のコードを実行するときに表示されるはずです2つのアラートの間に作成されます。

+0

私はあなたがそれが関数func2()関数 – MIrrorMirror

+0

ない@MIrrorMirrorああ、うーん、はいと言う示唆し何場合 - に開催! – Alnitak

+0

@Alnitak彼のコードを読んでください、func2は公共の機能ではありません。 – xdazz

0
function ctest() { 
    this.var1 = "haha"; 
    this.func1 = function() { 
     alert(this.var1); 
     func2(this); 
     alert(this.var1); 
    } 
    var func2 = function(obj) { 
     obj.var1 = "huhu"; 
    } 
} 

そして、この問題を解決するための他の方法があり、他の回答をチェック:)

+0

downvoterはあなたの理由を与えるべきです。 – xdazz

+0

@Alnitakしかし、それは問題ではないでしょう、 'obj'はパラメータです。 – xdazz

12

機能がインスタンスに縛られていない、したがって、func2のあなたの呼び出しは、呼び出しとして終わるthisせずに、予想されるインスタンスを指しています。

あなたは、コンテキストが含まれるように呼び出しを修正することができ、次のいずれか

function ctest() { 
    this.var1 = "haha"; 
    this.func1 = function() { 
     alert(this.var1); 
     func2.call(this); 
     alert(this.var1); 
    } 
    var func2 = function() { 
     this.var1 = "huhu"; 
    } 
} 

それとも、周りの指名手配オブジェクト参照の変数を保つことができます。

function ctest() { 
    var that = this; 
    this.var1 = "haha"; 
    this.func1 = function() { 
     alert(this.var1); 
     func2(); 
     alert(this.var1); 
    } 
    var func2 = function() { 
     that.var1 = "huhu"; 
    } 
} 
+0

ありがとう!ます。https://developer.mozillaこれは私 –

+0

はあなたが私がベストプラクティスと、なぜ私が提案する – InsOp

+1

@InsOpは「この」キーワードのMDNのヘルプを読んでいるかを知りたいと、さらに、このトピックで読んで提供することができますたくさん助け。org/en-US/docs/Web/JavaScript/Reference/Operators/this – Lucero

2

別のオプションは、Function.bindを使用することです:

function ctest() { 
    this.var1 = "haha"; 
    this.func1 = function() { 
     alert(this.var1); 
     func2(); 
     alert(this.var1); 
    } 
    var func2 = function() { 
     this.var1 = "huhu"; 
    }.bind(this); 
} 

ブラウザのサポートは完全ではありません。

+0

なぜ 'that' _and_' .bind() 'を同時に使うのですか? – Alnitak

+0

@Alnitak:コピーと貼り付けが不十分 – Eric

2

JSではプライベートなものはありませんが、closuresを使用してスコープで再生することができます。

たとえば、あなたの例では、公開プロパティとしてvar1を公開する必要はありません。彼らは同じ変数にアクセスすることができます - 彼らはctest、同じ関数内で定義されています -

function ctest() { 
    var var1 = "haha"; 

    this.func1 = function() { 
     alert(var1); 
     func2(); 
     alert(var1); 
    } 

    var func2 = function() { 
     var1 = "huhu"; 
    } 
} 

func1両方のでとfunc2株式同じスコープ:次のように簡単にコードを書き換えることができます。もちろんその場合はvar1が公開されていないので、myobj.var1undefinedになります。

あなたはvar1は、プロパティとして公開することにしたい場合は、何が必要あなたはコンストラクタで作成されたオブジェクトインスタンスへbindfunc2です:

function ctest() { 
    this.var1 = "haha"; 
    this.func1 = function() { 
     alert(this.var1); 
     func2(); 
     alert(this.var1); 
    } 
    var func2 = function() { 
     this.var1 = "huhu"; 
    }.bind(this); 
} 

そうでない場合func2が異なるコンテキストオブジェクト(this)を持つことになります。ブラウザはbindをサポートしていないとあなたが(上記のリンクに示すように)シムを使用したくない場合は、再びクロージャの利点を活用することができます

function ctest() { 
    this.var1 = "haha"; 
    this.func1 = function() { 
     alert(this.var1); 
     func2(); 
     alert(this.var1); 
    } 
    var context = this; 
    var func2 = function() { 
     context.var1 = "huhu"; 
    } 
} 

IMVHOはあまりエレガントです。

関連する問題