2016-09-12 7 views
0

thisの私の全体的な理解が大気圏に投げ込まれていると感じています。これをオブジェクトメソッドで使用するとエラーが返されます

私はQuizオブジェクトを持っています。このオブジェクトには、クイズの再生に必要な変数とメソッドがあります。

クイズの方法をクイズの別の方法(getQuestion in skipQuestion())から参照しようとしていますが、this.getQuestionが定義されていないというメッセージがコンソールに表示されています。私はこの場合のthisがそのオブジェクトを参照しているという印象の下にあったので、問題の機能はthis.getQuestion()と呼ばれるべきです。

私は取得していますエラーメッセージは、誰もがここで間違って何が起こっているか説明できscript.js:18 Uncaught TypeError: this.getQuestion is not a function

のですか?私init機能で

thisQuizオブジェクトを指しているようですが、skip questionに変更するようです。これは、thisという別の定義を持つクエリに対応していますか?どこで線を描くのですか?thisのコンテキストはいつ変更されますか?

(function(window){ 

    $(document).ready(function(){ 
     var Quiz = { 

      score : 0, 
      question: '', 
      answer: '', 

      init: function() { 
       this.getQuestion(); 
       this.checkAnswer(); 
       this.skipQuestion(); 
      }, 

      skipQuestion: function() { 
       $('#skip').click(function(){ 
        this.getQuestion(); 

       }) 
      }, 

      getQuestion: function() { 
       $.get('http://jservice.io/api/random', function(data){ 
        $('#question').html(data[0].question); 
        this.answer = data[0].answer.toLowerCase(); 
       }); 
      }, 

      checkAnswer: function() { 
       if($('#answer').val() === this.answer) { 
        this.score += 1; 
       } 
      } 
     } 

     Quiz.init(); 
    }); 

})(window); 
+1

別の関数の中に入ると、 'this'コンテキストが変更されます。別のファンクションブロックを開く前に、別の変数として使用したい 'this'を格納する必要があります。あるいは、二重矢印関数を使用して、そのようなコンテキストを使用しないでください。問題は次のとおりです: 'function(){this.getQuestion(); }} 'これは次のようにして解決できます:' var that = this;関数(){this.getQuestion(); '()=> {this.getQuestion()}'(それに関連する 'this'オブジェクトはありません) – somethinghere

+1

矢印機能を使用するにはES6 envを実行する必要があることに注意してください。 – azibi

+1

@何かがありますが、私の 'init()'関数は 'skipQuestion'ではなく' this'を使って他の機能を知っています。方法?それは 'this'の意味が違っているのか? –

答えて

1

あなたが別の関数内でネストされているので、thisコンテキストは機能に変化しないので、あなたが求めている方法は、もはや利用可能です。 thisを、定義している関数の範囲内にある変数の中に格納するか、または関連するthisコンテキスト自体を持たないDouble Arrow Functionsを使用して解決することができます(そのため、bindもサポートされません)。またはcall)。ここにあなたのオプションは次のとおりです。

は変数を宣言します。

skipQuestion: function() { 
    var that = this; 
    $('#skip').click(function(){ 
     that.getQuestion(); 
    }) 
} 

またはダブルアロー機能

skipQuestion: function() { 
    var that = this; 
    $('#skip').click(() => that.getQuestion()) 
} 

あなたのinit関数は、あなたのクイズオブジェクトの方法、しばらく考えられています匿名 clickイベントに渡される関数はではないメソッドoあなたのクイズは、匿名オブジェクトのメソッドで、バックグラウンドで作成され、クイズにメソッドや変数を共有しません。これは検討することが重要です!

+0

しかし、他の機能の中にいるほど簡単ではありませんか? 'init'関数の' this'はQuizオブジェクトを参照していますか? –

+0

それは実際にはそれと同じくらい簡単です。他の関数の中にネストするとすぐに、 'this'はレベルより上位の関数ではなく、_that_関数を参照します。すべての 'function'は新しい' this'コンテキストを取得します。これは空になります。しかし、オブジェクトに直接結び付けられた関数は、オブジェクトに設定された 'this'を取得します。無名関数は明らかにそうではありません。 – somethinghere

+0

ok!この場合、私の 'init'関数の' this'は 'Quiz'を指していますか?もしそうなら、理由を説明できますか? –

0

事は、あなたがクリックイベント内thisを使用しているであり、それはあなたのコンテキストではなく、イベントを指します。回避するには、これを別の変数に代入してから使用する必要があります。

 skipQuestion: function() { 
      var self = this; 
      $('#skip').click(function(){ 
       self.getQuestion(); 

      }) 
     }, 

$.get.clickイベントは、独自のコンテキストを作成し、こうしてthis代わりクイズの文脈のそれらのコンテキストを指します。

JS

(function(window){ 

    $(document).ready(function(){ 
     var Quiz = { 

      score : 0, 
      question: '', 
      answer: '', 

      init: function() { 
       this.getQuestion(); 
       this.checkAnswer(); 
       this.skipQuestion(); 
      }, 

      skipQuestion: function() { 
       var self = this; 
       $('#skip').click(function(){ 
        that.getQuestion(); 

       }) 
      }, 

      getQuestion: function() { 
       var self = this; 
       $.get('http://jservice.io/api/random', function(data){ 
        $('#question').html(data[0].question); 
        self.answer = data[0].answer.toLowerCase(); 
       }); 
      }, 

      checkAnswer: function() { 
       if($('#answer').val() === this.answer) { 
        this.score += 1; 
       } 
      } 
     } 

     Quiz.init(); 
    }); 

})(window); 
+0

ああ、これは 'this'が' init'の 'this'と異なる理由です'関数? –

+0

@phantomあなたはそれを正しく推測しました –

+0

なぜ '$ .get()'関数で変更されないのですか? – Adjit

関連する問題