• 追加された行はこの色です。
  • 削除された行はこの色です。
* setTimeout()とsetInterval() [#a90669de]
* コールバック関数が実行されるタイミング [#q7a461d3]

** タイマーで呼ばれるコールバック関数はグローバルスコープで実行される [#u2b4f8a6]
 var Foo = function () {
   this.num = 999;
   this.showNum = function () {
     alert(this.num);
   }
   this.showNumLater = function () {
     setTimeout(this.showNum, 1000);
   }
 };
 
 var foo = new Foo;
 foo.showNum();      // => 999
 foo.showNumLater(); // => Undefined
 (function () {
   console.log(1);
   setTimeout(function(){
     console.log('X');
   }, 3000);
   console.log(2);
   return;
   console.log(3)
 })()
 console.log(4)

showNumLater()から呼ばれるコールバック関数であるshowNum()はグローバルスコープで実行される。よって、this.numはグローバルオブジェクトを指す。this.numはFoo.numではない。
 1
 2
 4
 (3000ミリ秒待ってから)
 X

** すべてのタイマーをクリアする [#z5175a96]
"1"→"X"→"2"→"4"とはならない。

 for(var i = 1; i < 1000; i++) {
     clearTimeout(i);
 }
この方法でもタイマーIDに漏れがある事もあるらしい。

** タイマーで呼ばれるコールバック関数が引数を受け取る場合、無名関数でラップする [#v90a5e32]

 function foo(a,b) { console.log(a + "," + b); }
  
 setTimeout("foo(1,2)", 500);            
 setTimeout(function(){ foo(1,2) }, 500);
前者のように"foo(1,2)"のような文字列を渡してeval()する事も出来るが、後者のように無名関数を使う方がベタープラクティス。

以下の例ではグローバルのfoo()が呼ばれる。
 function foo() { console.log("1"); }
 function bar() { 
   function foo() { console.log("2"); }; 
   setTimeout("foo()", 500);
 } 
 bar(); // => "1


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS