2012-04-17 47 views
0

時,setTimeout不起作用,我試圖實現這樣的計時器。它有私有變量(秒,小時,分鐘)和三個公共方法:啓動,停止和繼續:在閱讀Douglas Crockford的「JavaScript:The Good Parts」之後,我使用Functional Inheritance

var timer = function() { 
      var that = {}; 
      var seconds = 0; 
      var hours = 0; 
      var minutes = 0; 
      var myTimer; 

      that.getTime = function() { 
       var time = hours + " : " + minutes + " : " + seconds; 
       return time; 
      } 
      that.start = function() { 
       seconds += 1;   
       if(seconds >= 60) { 
        seconds -= 60; 
        minutes += 1; 
       } 
       if(minutes == 60) 
        hours += 1; 
       document.getElementById('hours').innerHTML = hours; 
       document.getElementById('minutes').innerHTML = minutes; 
       document.getElementById('seconds').innerHTML = seconds; 
       myTimer = setTimeout(function() { 
        start(); 
       }, 1000); 
      }; 

      that.stop = function() { 
       clearTimeout(myTimer); 
      } 
      that.reset = function() { 
       seconds = 0; 
       hours = 0; 
       minutes = 0; 
       clearTimeout(myTimer); 
       document.getElementById('hours').innerHTML = hours; 
       document.getElementById('minutes').innerHTML = minutes; 
       document.getElementById('seconds').innerHTML = seconds; 
      } 
      return that; 
     }; 

,然後,我開始了它:

<body onload="var t = timer();t.start();"> 

    <h1>Digital Clock</h1> 
    <div id="wrap"> 
     <div> 
      <ul> 
       <li id="hours"></li> 
       <li> : </li> 
       <li id="minutes"></li> 
       <li> : </li> 
       <li id="seconds"></li> 
      </ul> 
     </div> 
    </div> 
    <br/> 
</body> 

誰能告訴我做了什麼錯誤我做 ?

更新:最後,我發現了問題。當你使用函數從另一個函數(比如,內部函數),「這」必將全球,不是外部函數中。因此,在語句start()中,js將嘗試在全局對象中查找函數。當然,沒有這樣的功能。在這裏,我發現了兩個解決方案:

  1. 使用 「即」

    myTimer = setTimeout的(函數(){ that.start();} ,1000);

  2. 保存上下文:

    變種timerInstance =此; ()函數(){ timerInstance.start(); },1000);

希望這會幫助你。

+3

你應該學習如何使用** **控制檯來看看你的程序產生了什麼錯誤。您通常可以通過在瀏覽器(或Google)中按F12來執行此操作。對於* one *,您應該在'start()'和'continue()'函數中使用'this.start()',而不是*只使用''start()'。您還應該將'setTimeout()'的結果賦值給'myTimer',以使您的'stop()'函數正常工作。 – Matt 2012-04-17 09:55:37

+1

@Matt在這個特定的實例上它是'that.start()',而不是'this.start()'。這種繼承的實現是絕對不必要的,我不確定,他們爲什麼要這樣教。 – joncys 2012-04-17 10:04:22

+0

@joncys:的確你是對的。以及拾取;)(雖然我不能糾正我原來的評論,因爲它現在超出了5分鐘的窗口:)) – Matt 2012-04-17 10:06:03

回答

0

下面是一個包含修改後的代碼的jsfiddle:http://jsfiddle.net/6YWLJ/

我把它換成「是」與「此」(「這」代表你的計時器),並代替「VAR計時器」我使用「窗口.timer」

後來編輯:這是不正確的碼版本,因此它就像一個計時器(你必須在你的代碼的一些錯誤)http://jsfiddle.net/6YWLJ/2/

+0

謝謝,但你知道爲什麼它不適用於「那個」嗎?也許我使用這個模板的方式對你來說看起來很陌生,但是當我正在閱讀那本書時,我只想盡可能地知道:) – nxhoaf 2012-04-17 10:47:51

+0

我不確定。這可能不是因爲「那個」,而是因爲「var timer」而不是「window.timer」。這裏是工作jsFiddle更新與「that」:http://jsfiddle.net/6YWLJ/5/ – gabitzish 2012-04-17 10:54:05

+0

謝謝!我發現這個錯誤,這是Crockford在他的書「當一個函數被調用這個模式(方法調用模式)時所說的,這是綁定到全局對象的,這是語言設計中的一個錯誤。設計正確,當內部函數被調用時,這仍然會被綁定到外部函數的這個變量上,這個錯誤的後果是一個方法不能使用一個內部函數來幫助它完成它的工作,因爲內部函數不會共享該方法對象的訪問權限,因爲它綁定了錯誤的值...「 – nxhoaf 2012-04-17 11:10:12