javascript中setTimeout()函數

來源:互聯網
上載者:User

 

 

大家都知道javascript中的setTimeput()函數的作用,一般會用他來處理一些連續的事情,們先看一個例子:

<head>
    <script>
        function init()
        {
            setTimeout("init2()",0);
            alert("1");
        }
        function init2()
        {
            alert("2");
        }
    </script>
</head>
<body onload="init()">
</body> 

也許很多人認為結果是:2 1, 而恰恰結果是:1  2 。這是為什麼呢?明明延遲時間設定的是0,應該是立刻先執行init2()啊?我們可以這樣認為,setTimeout()函數會自己重新申請一個堆棧空間,而不屬於當前函數init()的堆棧空間,所以init()先入棧,alert("1")第2個入棧,當init()函數執行完後,setTimeout()才執行。
 
當然這裡沒有涉及到參數傳遞,再看這個例子:

<head>
<script>
  var rgbcolor=new Array(3);
  var whichtr=0;
  function changeColor(wh)
  {
  whichtr=wh;
  for(var i=0;i<3;i++)
  {rgbcolor[i]=Math.ceil(Math.random()*255);}
  trID[whichtr].style.backgroundColor="rgb("+rgbcolor[0]+","+rgbcolor[1]+","+rgbcolor[2]+")";
  setTimeout("changeColor("+whichtr+")",1000);
  }
  
</script>
</head> <body>
<table border="1" height="400" width="500" align="center" cellspacing="0">
  <tr onmousedown="changeColor(0)" id="trID"><td>0</td></tr>
  <tr onmousedown="changeColor(1)" id="trID"><td>1</td></tr>
  <tr onmousedown="changeColor(2)" id="trID"><td>2</td></tr>
</table>
</body>

 

當我們在表格裡分別單擊3個行的後,3個行的背景顏色會分別一直變顏色.這裡我們就會要問:當我點擊第一行後,whichtr=wh=0;當我們點擊第2行後,whichtr=wh=1;此時whichter全域變數已經發生變化了,但此時第一行的顏色還在變化,點擊第3行後,前面兩行的顏色也一直變化,這是為什麼呢?全域變數只有一個whichtr,可是他明明在我們單擊後就改變了,但是3行的顏色一直變化,我們所期待的應該是每次點擊後只有一行的顏色在改變。
為了看的更清楚的知道全域變數whichtr在程式啟動並執行時變化,我們加入一句代碼:document.body.innerHTML+=whichtr;
指令碼代碼變為:

<script>
  var rgbcolor=new Array(3);
  var whichtr=0;
  function changeColor(wh)
  {
  whichtr=wh;
  for(var i=0;i<3;i++)
  {rgbcolor[i]=Math.ceil(Math.random()*255);}
  trID[whichtr].style.backgroundColor="rgb("+rgbcolor[0]+","+rgbcolor[1]+","+rgbcolor[2]+")";
  document.body.innerHTML+=whichtr;
  setTimeout("changeColor("+whichtr+")",1000);
  }
</script> 

 
此時,我在分別單擊表格的三行,結果是:三上的顏色都在改邊,whichtr的值是:012012012012...
這時,我們可以知道,全域變數發生了變化,而且一直在變化。
為什嗎?關鍵問題是這句代碼:setTimeout("changeColor("+whichtr+")",1000);
我們可以這樣來分析:
  當單擊第1行後,whichtr的值是0,當程式執行到setTimeout("changeColor(”+whichtr+")",1000)時,就會把0當作1000MS後執行changeColor()函數的參數.前面我們已經知道,setTimeout函數在記憶體中會重新申請一個堆棧來儲存要啟動並執行函數,所以,此時的whichtr=1已經被儲存到另外一個記憶體單元中了,但這不是本來的whichtr,只能說是一個whichtr的拷貝,當1000MS時間周期到的時候,就會把whichtr==1這個拷貝當做參數傳遞給changeColor(),執行到whichtr=wh;時,才真正改邊了whichtr這個全域變數的值.
程式中每一個onmousedown事件就會產生一個堆棧空間,每一個堆棧空間內都會有一個changeColor()函數,但是全域變數whichtr是共有的,每個堆棧內獨立的運行,但這並不是多線程,javascript是單線程的,這隻能算一個類比多線程吧。

總結:
  setTimeout()函數在傳遞參數的時候,是將一個參數的拷貝儲存在setTimeout()所在的新的堆棧中,時間周期到的時候,將這個拷貝傳遞給調用函數。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.