1. 説明
1. 概要
setTimeout: 指定された遅延時間の経過後に関数を呼び出すか、コードフラグメントを実行します
setInterval: 定期的に関数を呼び出すか、コードの一部を実行します。
2. 文法
setTimeout:
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]); var timeoutID = window.setTimeout(code, delay);
var intervalID = window.setInterval(func, delay[, param1, param2, ...]); var intervalID = window.setInterval(code, delay);
<script type="text/javascript"> setTimeout( function(param){ alert(param)} , 100, 'ok'); </script>
私のコンピューターで Firefox と IE9 を使用して、5 番目の項目を簡単にテストしました。前者はスムーズに表示されますが、後者は未定義のまま表示されます。
2. 「これ」の質問setTimeout() によって呼び出されるコードは、そのコードが配置されている関数とは完全に別の実行環境で実行されます。これにより、これらのコードに含まれる this キーワードが、異なるウィンドウ (グローバル オブジェクト) オブジェクトを指すようになります。予想通り、これは値が同じではありません。 setInterval の状況も同様です。
<script type="text/javascript"> //this指向window function shape(name) { this.name = name; this.timer = function(){alert('my shape is '+this.name)}; setTimeout(this.timer, 50); } new shape('rectangle'); </script>
渡されませんでした。chrome、firefox、IE9で試してみましたが、結果は同じでした。
解決策 1:
<script type="text/javascript"> function shape(name) { this.name = name; this.timer = function(){alert('my shape is '+this.name)}; var _this = this; setTimeout(function() {_this.timer.call(_this)}, 50); } new shape('rectangle'); </script>
関数は、JavaScript クロージャーのおかげで、ローカル変数 _this を呼び出すことができます。これにはスコープ チェーンやその他の知識が含まれますので、興味がある方はご自身で学習してください。ここでは説明しません。
解決策 2:この方法は少し派手です。カスタマイズされた setTimeout と setInterval。また、IE ブラウザの以前のバージョンが遅延関数への追加パラメータの受け渡しをサポートしていないという問題も拡大します。
<script type="text/javascript"> //自定义setTimeout与setInterval var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval; window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) { var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeST__(vCallback instanceof Function ? function () { vCallback.apply(oThis, aArgs); } : vCallback, nDelay); }; window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) { var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2); return __nativeSI__(vCallback instanceof Function ? function () { vCallback.apply(oThis, aArgs); } : vCallback, nDelay); }; function shape(name) { this.name = name; this.timer = function(other){ alert('my shape is '+this.name); alert('extra param is '+ other); }; } var rectangle = new shape('rectangle'); setTimeout.call(rectangle, rectangle.timer, 50, 'other'); </script>
2. setTimeout と setInterval を拡張し、aArgs は引数変数を分割することで追加のパラメーター配列を取得します
3. vCallback instanceof Function を使用して、これが関数であるかコードであるかを判断します。関数の場合は、apply を使用して実行します。
4. SetTimeout は呼び出しで実行され、このオブジェクトと他の関数、遅延、その他のパラメーターを設定します5. setTimeout を拡張することで、IE の以前のバージョンを使用するブラウザでも追加のパラメータを実行できます
3. setTimeout と setInterval の違い
看上去,两个功能是差不多的,但是里面其实是不一样的。
setTimeout回调函数的执行和上一次执行之间的间隔至少有100ms(可能会更多,但不会少于100ms)
setInterval的回调函数将尝试每隔100ms执行一次,不论上次是否执行完毕,时间间隔理论上是会<=delay的。
setInterval:
<script type="text/javascript"> function sleep(ms) { var start = new Date(); while (new Date() - start <= ms) {} } var endTime = null; var i = 0; setInterval(count, 100); function count() { var elapsedTime = endTime ? (new Date() - endTime) : 100; i++; console.log('current count: ' + i + '.' + 'elapsed time: ' + elapsedTime + 'ms'); sleep(200); endTime = new Date(); } </script>
从firefox的firebug可以查看到,时间间隔很不规则。
情况大致是这样的:由于count函数的执行时间远大于setInterval的定时间隔,那么定时触发线程就会源源不断的产生异步定时事件,并放到任务队列尾而不管它们是否已被处理,但一旦一个定时事件任务处理完,这些排列中的剩余定时事件就依次不间断的被执行。
setTimeout:
<script type="text/javascript"> function sleep(ms) { var start = new Date(); while (new Date() - start <= ms) {} } var endTime = null; var i = 0; setTimeout(count, 100); function count() { var elapsedTime = endTime ? (new Date() - endTime) : 100; i++; console.log('current count: ' + i + '.' + 'elapsed time: ' + elapsedTime + 'ms'); sleep(200); endTime = new Date(); setTimeout(count, 100); } </script>
以上就是本文的全部内容,希望对大家学习javascript定时器有所帮助。