好きなだけかりんとうを食べる人生

フロントエンドとかデザインとかバックエンドとか浅く広く。社会人3年目のうぇぶでぃれくたーです。

setTimeout()メソッドのひみつ

こんばんは。 GJ部おもしろいんじゃあ^〜

setTimeout()とは?

setTimeout()はご存知の通り、引数に指定した関数を遅延して実行するメソッドです。

setTimeout(function() {
  console.log("ほげ");
}, 1000);

※今回はサンプルなのでclearTimeout()でタイマー処理を解除していませんが、場合によってはsetTimeout()メソッドが内部の関数を参照し続けることによってgcの対象にならないケースもあります(=クロージャ)。ちゃんとclearしようね。

そんなsetTimeoutですが、web上でサンプルコードを漁っていると時々このようなコードを見かけます。

setTimeout(function() {
  // 処理
}, 0);

setTimeout()の注意点

普通に考えればsetTimeoutが評価された瞬間に内部の処理が実行されますが、 例えば以下のようなケースだと、

var hoge = function() {
    setTimeout(function() {
      console.log("GJ部");
    }, 0);
}
hoge();
console.log("おもしろいんじゃあ^〜");
"おもしろいんじゃあ^〜"
"GJ部"

このように出力されます。 みんな大好きサイ本によると、

setTimeout() を使った便利なテクニックの1つに、0 秒後に関数が呼び出されるというものがある。 このような形式で setTimeout() を呼び出すと、イベントハンドラの実行が完了し、ドキュメントの更新状態が終了した時点で、 指定した関数が呼び出される。ドキュメントコンテンツを取得したり、変更したりするイベントハンドラはこのテクニックを使って ドキュメントが安定した状態になるまでコードの実行を遅らせる必要がある。

とあります。 つまり、関数を代入したhogeの評価が終わるまでsetTimeoutの内部関数は呼び出されないんですね。

まとめ

setTimeoutの第二引数に0msを指定する=関数を即時実行するというわけではないんですね。 つまり、setTimeout()を利用することによって、DOMを構築したりイベントを実行した後に処理を実行することができるということでしょうか。色々試してみようと思います。

追記

ちなみにsetTimeout()の第二引数に0msを指定しても厳密には0msで処理が実行されるわけではなく、ブラウザ毎に最小指定可能引数が決まっています(chromeやffは4msとかだった気がする)。 リサイズ関連のメソッドでもsetTimeoutを使った便利なパターンを見つけたので、今度記事にしようと思います。