2013-09-25 9 views
13

के भीतर रिकर्सिव कॉल ठीक है इसलिए मेरे पास यह प्रोटोटाइप ऑब्जेक्ट चरण है, और इसके प्रत्येक भाग इस रिकर्सिव कॉल को छोड़कर काम करता है।प्रोटोटाइप फ़ंक्शन

Stage.prototype.start = function(key) { 
     //var maxScrollLeft = document.getElementById("content").scrollWidth; 
     $content.scrollLeft($content.scrollLeft() + this.initspeed); 
     if(key < this.maxScrollLeft || key > 0) { 
       setTimeout(function() { 
         this.start(key+2); 
       },1); 
     }else{ 
       console.log("stop"); 
     } 
} 

इम this.start का उपयोग कर, ताकि Stage.prototype.start इस के भीतर कहा जाता है अगर बयान में यह करने की कोशिश कर(); हालांकि मुझे हमेशा Uncaught TypeError: Object [object global] has no method 'start' मुझे लगता है कि इसे किसी अज्ञात फ़ंक्शन में कॉल के साथ करना है, इस पर कोई विचार है कि मैं इसे कैसे ठीक कर सकता हूं?

उत्तर

20

this वैश्विक वस्तु पर सेटटाइमआउट बिंदुओं के आपके अज्ञात कॉलबैक के अंदर, क्योंकि फ़ंक्शन कहीं भी बाध्य नहीं है, इसलिए यह वैश्विक दायरे में फंस जाता है। इस मामले में आपके कॉलबैक को window (ब्राउज़र) या global (नोड, इत्यादि) संदर्भ से this अंक वैश्विक दायरे में निष्पादित किया गया है, क्योंकि उस संदर्भ से फ़ंक्शन को कॉल किया जाता है। इस मुद्दे पर पहुंचने के कई तरीके हैं। एक आसान तरीका this को एक चर में कैश करना और कॉलबैक फ़ंक्शन में इसका उपयोग करना है।

Stage.prototype.start = function(key) { 
      var self = this; //cache this here 
      //var maxScrollLeft = document.getElementById("content").scrollWidth; 
      $content.scrollLeft($content.scrollLeft() + this.initspeed); 
      if(key < this.maxScrollLeft || key > 0) { 
        setTimeout(function() { 
          self.start(key+2); //use it to make the call 
        },1); 
      }else{ 
        console.log("stop"); 
      } 
    } 

Fiddle

एक और तरीका है आप कर सकते हैं एक संदर्भ function.prototype.bind का उपयोग कर बाध्य करने के लिए है।

Stage.prototype.start = function(key) { 
      //var maxScrollLeft = document.getElementById("content").scrollWidth; 
      $content.scrollLeft($content.scrollLeft() + this.initspeed); 
      if(key < this.maxScrollLeft || key > 0) { 
        setTimeout((function() { 
          this.start(key+2); //now you get this as your object of type stage 
        }).bind(this),1); //bind this here 
      }else{ 
        console.log("stop"); 
      } 
    } 

Fiddle

संबंधित मुद्दे