2017-08-26 15 views
0

JavaScriptの他の関数内から設定や値/関数にアクセスしようとしていますが、おそらく私が欠けている単純なルールがあると考えています。ここでは非常に単純化されたコードの例です:JavaScript関数内の異なる場所を参照する方法

function h(){ 
    // example settings I want to declare for h() 
    this.settings = { 
     critical: 400, 
     readCritical: function(){ 
      return this.settings.critical; // /!\ but this does not work 
     } 
    } 
    this.hsub = function(){ 
     return this.settings.critical; // /!\ this does not work either 
    } 

} 
var x = new h(); 
console.log(x.settings.critical); // This works fine 
console.log(x.settings.readCritical()); // I can *call* this fine, but it can't read outside itself 
console.log(x.hsub()); // I can also call this but same problem 
console.log(h.settings); // `undefined`; I understand I can't see directly into the function 

あなたは、私はそれぞれの機能readCriticalhsub内部からアクセスしようとしているthis.settings.critical値を、見ることができます。これどうやってするの?特にインスタンス化されたxから。

また、2番目の質問にもかかわらず、私はthis.settingsの代わりにvar settings = {}と宣言することをお勧めします。これは可能か、それとも好ましいのでしょうか?

+0

'h.settings'は何を返すのですか?すべてのインスタンスの設定がまったく同じだと考えていますか?なぜなら、いくつかのインスタンスは 'x.settings.critical = 200'で区別できるからです。だから、あなたは200でいくつか、400でいくつか、そして「h.settings.critical」はどうしたらいいのですか?また、なぜあなたは 'var設定'を好むのですか?どのように '設定'を公開するのですか? – trincot

+0

質問はたくさんありますが、 'h.settings'はオブジェクトであり、何も返さないはずですが、' x.settings.something'が値を返すようにしたいと思います。私はちょうど要素にイベントバインディングを添付するために 'h()'を呼びたいと思っていますが、 'x'で積極的に作業することはしばしばあります。私の考えでは、複数のインスタンスを独立して動作させることができれば、コードをうまく書くテストです。これまでのところ、「var設定」が好きなように、私は過去にそのように書いていますが、受け入れられた回答では、「this」を使うことはまあまあだと思います。 –

+0

あなたはシングルトンパターンを探していますか?注:現在、 'h.settings'は存在しません。 – trincot

答えて

2

のみを作成する際に必要な変更はreadCritical関数内から.settingsを削除することです。

hsubはそのまま動作します。あなたはそこに問題

function h(){ 
 
    this.settings = { 
 
     critical: 400, 
 
     readCritical: function(){ 
 
      return this.critical; // reference `critical` directly 
 
     } 
 
    } 
 
    this.hsub = function(){ 
 
     return this.settings.critical; // this works just fine 
 
    } 
 

 
} 
 

 
var x = new h(); 
 

 
console.log(x.settings.critical);  // 400 
 
console.log(x.settings.readCritical()); // 400 
 
console.log(x.hsub());     // 400 
 

 
// This is expected to be `undefined` 
 
console.log(h.settings);

+0

'readCritical()'がそれを探す必要があり、 'hsub()'が小さなコードスニペットで見る必要があるところの違いは、非常に参考になります。それは私のためだった。これは、私の質問の最も簡単なアプリケーションのコードの最小行を使用しているようだ。 –

+0

よろしくお願いいたします。 'this'の値は一般に呼び出し元によって定義されます。通常、 'this'が何であるかを判断するために呼び出されるオブジェクトとメソッドを分離する' .'の左側を見ることができます。しかし、呼び出す前にそれらを切り離せば、それは違うでしょう。 'var fn = x.settings.readCritical; x(); '' x 'は 'readCritical'を参照しますが、' settings'には接続しません。 – spanky

+0

@ Me.Name:正しい。あなたの上の私のコメントはその警告を与えます。 ;-) – spanky

1

もう古い古典的なクロージャの問題です。

それを解決するには、2つの方法があります。

function h(){ 
    var self = this; 
    this.settings = { 
     critical: 400; 
     readCritical: function() { 
      return self.settings.critical(); // otherwise this.settings will 'cover' `this`. 
     } 
    } 
} 

readCritical:() => this.settings.critical(); // arrow functions won't form a function scope 
+1

本当にクロージャの問題ではありません。これは「this」の価値の問題です。矢印関数は間違いなく関数スコープを形成します。彼らは 'this'束縛を定義していません。 – spanky

1

thisの範囲だった(と、それを設定するための機能を結合)と思った理由はわからないくらいのJSでのトピックを議論しています。しかし、具体的にはthisを探しているわけではないようですが、変数を共有することもできます。まったくいい答えはありませんが、var settings = {}も宣言したいので、他の関数で使用できるローカル変数に実際にアクセスすることができます。

function h(){   
 
    var settings = { //var settings is a local variable of the function h (or instance of it). If ES6 is allowed 'let' or 'const' are preferrable 
 
     critical: 400, 
 
     readCritical: function(){ 
 
      return settings.critical; 
 
     } 
 
    }; 
 
    this.settings = settings; //this.settings is not the same variable as var settings, making this statement valid 
 
    this.hsub = function(){ 
 
     return settings.critical; //the local (var) settings is used 
 
    } 
 
} 
 

 
var x = new h(); 
 
console.log(x.settings.critical); 
 
console.log(x.settings.readCritical()); 
 
console.log(x.hsub());

ここに落とし穴、(彼らはx.settings内の値を変更した場合、すべてが順調である)は、呼び出し元のコードが他のものにx.settingsを変更した場合、変数が同じインスタンスを指していますということです。それがリスクの場合は、代わりにプロパティメソッドとして公開される可能性があります。

1

1つのインスタンスだけを持つように見えます。それがそうであるならば、単にオブジェクトリテラル表記ですぐにインスタンスを作成します。

var h = { 
 
    settings: { 
 
     critical: 400, 
 
     readCritical: function(){ 
 
      return this.critical; 
 
     } 
 
    }, 
 
    hsub: function(){ 
 
     return this.settings.critical; 
 
    } 
 
} 
 
console.log(h.settings.critical); 
 
console.log(h.settings.readCritical()); 
 
console.log(h.hsub()); 
 
console.log(h.settings);

予想通りシングルトンオブジェクトh与えられたときに今、すべての4つのプロパティが仕事にアクセスします。

関連する問題