console.lealog();

@leader22のWeb系に関する勉強めもブログですのだ

「はてな教科書」のJavaScriptの課題をやってみた・・けど

こんなエントリがありまして。

参考:「はてな教科書」をgithub上に公開しました - Hatena Developer Blog

せっかくなので、JavaScriptの章にあった課題をやってみました。
けど・・・。

JavaScript力 が たりない !

一応動きはするものの、なんかこうしっくりこないというか・・。
どなたか添削・アドバイスいただけると非常に助かりますです。

お題

タイマーを管理する Timer クラスをつくれ。

仕様

var timer = new Timer(time);
    //=> time ミリ秒のタイマーを作る
timer.addListener(callback1);
    //=> タイマーが完了したときに呼ばれる関数を追加する
    //=>  callback : Function => タイマーが完了したときに呼ばれる関数
timer.addListener(callback2);
    //=> タイマーが完了したときに呼ばれる関数は、複数指定できる
timer.start();
    //=> タイマーをスタートさせる。
    //=> start() してからコンストラクタに指定したミリ秒後に addListener に指定したコールバックが呼ばれる
timer.stop();
    //=> タイマーをストップさせる。

var timer = new Timer(1000);
timer.addListener(function (e) {
  alert(e.realElapsed); //=> start() 時から実際に経過した時間
  timer.start(); //=> 再度スタートできる
});
timer.start();

document.body.addEventListener('click', function () {
  timer.stop(); //=> クリックで止まる。
}, false);

この例ですが、2行目の意味がわからなかったのでやってません。
定義したaddListener関数にまたstart関数で再度スタート?うーん、わからん。

なので、仕様の項に書かれた内容のみを実装してみました。

書いてみた

Html

<button id="start">Start!</button>
<button id="stop">Stop!</button>

JavaScript

(function(){
	/* 呼び出し用ダミー関数 */
	function myFunc1(){console.log('Func1');}
	function myFunc2(){console.log('Func2');}
	
	/* Timerクラス */
	var Timer = function(time){
		// 設定用のプロパティ
		this.settings = {
			timerCount:time,// 何秒後に動かすか
			timerVal:[],// タイマー変数入れ
			timerFunc:[],// 各タイマー変数に対応する、関数入れ
			queueFunc:0// 一括スタート・ストップ用のショートカット
		};
		
		// タイマーにセットする関数を受ける
		this.addListener = function(func){
			this.settings.timerFunc.push(func);
			this.settings.queueFunc = this.settings.timerFunc.length;
		};
		
		// タイマーをスタート
		this.start = function(){
			for(var i = 0; i < this.settings.queueFunc; i++){
				this.settings.timerVal[i] = setTimeout(this.settings.timerFunc[i], this.settings.timerCount);
			}
		};
		
		// タイマーをストップ
		this.stop = function(){
			for(var i = 0; i < this.settings.queueFunc; i++){
				clearTimeout(this.settings.timerVal[i]);
			}
		};
	};
	
	/* 3秒後に動くタイマーをセット */
	var timer = new Timer(3000);
	timer.addListener(myFunc1);
	timer.addListener(myFunc2);
	
	/* スタートとストップボタンの設置と、イベント設定 */
	var bt = {
		start:document.getElementById('start'),
		stop:document.getElementById('stop')
	}
	
	bt.start.addEventListener('click', function () {
		timer.start();
	}, false);
		
	bt.stop.addEventListener('click', function () {
		timer.stop();
	}, false);
})();

おもったこと

そもそも課題の内容と違うはず・・

再スタートできる・・みたいな文言もあるので、おそらくDateで時間も持たせてstop()されたら差分取るとか、それ用のプロパティとか必要なはず。
「コールバックを理解する」とのことなので、もっと複雑になるけどシンプルに記述するやり方が答えに近いはず。(今回のコレほとんどコールバックしてな・・)

removeListener

完全に見落としてて配慮してないです・・。
removeする=タイマーをクリアなはずなので、セットした関数名を引いてきてクリアすれば良いんかな?
でもその為にはArrayじゃなくてObjectでタイマー関数とか持たせた方が良かったかも?

でもそうするとlengthとかpushとかつかえなくなるような。
ここで、Array.prototype.push.apply(this, elem);ってやつか!

Prototype?

それらしく書いたつもりではいるものの、1つのオブジェクトとして作るより、メソッドとしてTimer.prototype.addListenerとかってした方が効率が良いのでは?と、今読んでる本を見てて感じたりも。
新しく newする度に変わる可能性のあるもの(今回はタイマーの秒数とか)と、そうじゃないものを使い分けるべきなんかな?

答えあわせ

やりたいものの、それらしきものが見当たらない!
答え合わせしたところで、「なるほど・・・」としか言えないんやろうけどw

うん、精進します・・。
こういうのは勉強になるなぁとは思うものの、やっぱり独学で踏み込むには若干きつくなってきたなぁ、とも。