2016-09-27 11 views
0

JavaScriptでクラスをコーディングしましたが、プライベート関数内のパブリックプロパティの1つを変更しようとしています。ここでJavascriptプライベート関数からパブリックプロパティを変更

は、私のコードの例です:

MyClass = function(callback){ 

    this.tabs = []; 
    var tabs_callback = function(){}; 

    this.setTabsCallback = function(callback) { 
     tabs_callback = callback; 
    } 

    var _doStuff = function(callback) { 

     // doing stuff 

     this.tabs = [1, 2, 3]; 

     console.log("Inside doStuff"); 
     console.log(this.tabs); 

     tabs_callback(); 
    } 

    this.doStuff = function() { 
     _doStuff(); 
    } 
} 


var myObject = new MyClass(); 

myObject.setTabsCallback(function() { 

    console.log("Inside callback"); 
    console.log(myObject.tabs); 
}); 

myObject.doStuff(); 

そして、ここでは、私は、コンソールで得るものです:

Inside doStuff 
[ 1, 2, 3 ] 
Inside callback 
[] 

なぜ私は、コールバック関数からの私の変更を見ることができないのですか?

+2

の範囲を「これ」。 'MyClass'関数の上に(おそらく' this.tabs = []; 'の上にある)変数' var self = this; 'を作り、' this'の代わりに 'self'を使います。公共の財産にアクセスする。 – jonhopkins

+0

すごい!あなたは正しい、それは働いた!どうもありがとうございました –

答えて

1

_doStuffを関数として定義されているので、それはあなたがプライベート関数の外で定義this.tabsにアクセスすることができない理由は、独自のthisコンテキストを持っています。

これを解決する簡単な方法が2つあります。

まず、あなたは、単に機能外thisへの参照を保持するプライベート変数を作成することができます。

... 
var that = this; 
var _doStuff = function(callback) { 
    // inside _doStuff, use "that" instead of "this" 
... 

あるいは、第二、あなたが代わりに矢印の機能を使用することができます。矢印機能は、Javascriptに比較的新しい機能です。彼らは独自のthis参照して別のコンテキストを作成していないので、あなたはthisオブジェクトを使用する場合、それはまだ機能外と同じオブジェクトを参照しますので、あなたの機能が正常に動作します:おそらく

.... 
var _doStuff = (callback) => { 
    // now _doStuff doesn't create a new "this" object, so you can still access the one from outside 
... 
1

this keywordを参照してください。矢印の機能を使用すると、これらの問題の多くを防止するための良い方法です:

var _doStuff = (callback) => { ...

しかし、あなたはまだそれを認識する必要があります。 (あなたがstrictモードである場合、またはnull)デフォルトでは

1

windowへのJSは、バインディング字句コンテキストを使用していない、とあなたは、通常の関数を呼び出すときに、thisデフォルト。

これを避ける方法はたくさんあります:前述のようにthisを変数に保存することができます。それは100%のケースで機能します。

Function#bindメソッドを使用して、_doStuffをコンテキストに明示的にバインドすることもできます。_doStuff = _doStuff.bind(this)のようにするか、_doStuff.bind(this)()のように呼び出すことができます。 IE9以前のIE(そしておそらく、いくつかの他のブラウザでは、わかりません)はbindをサポートしていません。

最後に矢印関数を使用することもできます。前述のとおり、これらは字句バインディングを使用しており、thisは期待どおりのものになります。矢印機能はES6から利用可能ですが、このようなコンストラクタを作成している場合は、ES6ではありません。

1

_doStuf

this.doStuff = function() { 
       _doStuff(); 
       } 

_doStuffのような機能によって呼び出されるグローバルオブジェクトにバインドされています。したがって、その定義をthisにバインドするか、_doStuff関数を呼び出すときに.call(this)を使用する必要があります。したがって、以下のようにコードを変更すると役立ちます。

MyClass = function(callback){ 
 

 
    this.tabs = []; 
 
    var tabs_callback = function(){}; 
 

 
    this.setTabsCallback = function(callback) { 
 
     tabs_callback = callback; 
 
    } 
 

 
    var _doStuff = function(callback) { 
 

 
     // doing stuff 
 

 
     this.tabs = [1, 2, 3]; 
 

 
     console.log("Inside doStuff"); 
 
     console.log(this.tabs); 
 

 
     tabs_callback(); 
 
    } // <<< you can either use .bind(this) here 
 

 
    this.doStuff = function() { 
 
     _doStuff.call(this); // <<< or use .call(this) here to bind _doStuff to the this 
 
    } 
 
} 
 

 

 
var myObject = new MyClass(); 
 

 
myObject.setTabsCallback(function() { 
 

 
    console.log("Inside callback"); 
 
    console.log(myObject.tabs); 
 
}); 
 

 
myObject.doStuff();

関連する問題