2012-04-17 6 views
0

ダグラス・クロフォードの「JavaScript:The Good Parts」を読んだ後、私はこのようなタイマーを実装しようとしました。これは、プライベート変数(秒、時間、分)と3つのpublicメソッドがあります、開始、停止および継続:機能継承を使用しているときにsetTimeoutが機能しない

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> 

誰が何をしたか、エラーを教えてもらえます私が作る ?

更新:最後に、私はあなたが別の関数(たとえば、内部機能)、「これは」、グローバルにバインドされていない外側の関数内から関数を使用するproblem.Whenを見つけました。したがって、文start()では、jsはグローバルオブジェクト内の関数を検索しようとします。もちろん、このような機能はありません。ここで、私は2つの解決策が見つかりました:

  1. 使用

    myTimer =のsetTimeout(; 1000関数(){ that.start()}) "ことを"。

  2. 保存コンテキスト:

    するvar timerInstance =この;

    myTimer = setTimeout(function(){ timerInstance.start(); }、1000);

希望すると、これが役立ちます。私は「この」で(「これは」あなたのタイマーを表します)「ということ」に置き換えてきましたし、「VaRのタイマー」i「は、ウィンドウを使用しました代わりにhttp://jsfiddle.net/6YWLJ/

:ここ

+3

あなたは**コンソールを使用する方法を学ぶ必要があります**:「.timer

後の編集あなたのプログラムによってどのようなエラーが生成されているのかを確認してください。通常は、ブラウザ(またはGoogle)内のF12キーを押してこれを行うことができます。 * one *の場合は、 'start()'ではなく 'start()'と 'continue()'関数内で 'this.start()'を使うべきです。また、 'setTimeout()'の結果を 'myTimer'に代入して' stop() '関数を正しく動作させる必要があります。 – Matt

+1

@Mattこの特定のインスタンスでは、 'this.start()'ではなく 'that.start()'です。継承のこの実装は絶対に不必要です、私は確信していません、なぜ彼らはこれを教えています。 – joncys

+0

@joncys:確かにあなたは正しいです。私は元のコメントを修正することはできませんが、今は5分のウィンドウの外にあります:) – Matt

答えて

0

は、あなたの変更されたコードを含むjsFiddleですにそれはタイマーのような役割を果たして、これは、修正されたコードのバージョンである(あなたのコード内のいくつかのバグを持っていた)http://jsfiddle.net/6YWLJ/2/

+0

ありがとうございます。しかし、なぜ「それ」でうまくいかなかったのか分かりますか?おそらく私がこのテンプレートを使用する方法は見知らぬ人に見えますが、私はその本を読んでいるので、できるだけ多くを知りたいだけです:) – nxhoaf

+0

私は分かりません。それは "that"のせいではなく、 "window.timer"ではなく "var timer"のせいかもしれません。ここで、 "that"で更新された作業jsFiddleがあります:http://jsfiddle.net/6YWLJ/5/ – gabitzish

+0

ありがとうございました!私はこのエラーを発見しました。ここではCrockfordが "このパターン(メソッド呼び出しパターン)で関数が呼び出されると、これはグローバルオブジェクトにバインドされます。これは言語の設計上の間違いでした。内部関数が呼び出されたときに正しく設計されていれば、これは外部関数のこの変数に依然としてバインドされている可能性があります。 内部関数を使用すると、内部関数これが間違った値にバインドされているので、オブジェクトへのメソッドのアクセスを共有しません... " – nxhoaf

関連する問題