setTimeout 第一個參數


今天有人在群里問setTimeout第一次參數為字符串的時候為什么會報錯,代碼如下:

 function display(obj)
{
    obj.style.display='none';
    window.setTimeout("obj.style.display='inline'", 500);
}

報obj is not defined。

經過我自己測試了列子,自己總結出了幾個結論,真實性有待考證。下面講講我的例子與結論。

首先,setTimeout的第一個參數分為3類,1.字符串代碼 2.method 3.function 。

1.字符串代碼:

function display(obj)
{
    obj.style.display='none';
    window.setTimeout("obj.style.display='inline'", 5000);
}

當setTimeout第一個參數為字符串代碼時,執行這段代碼會報obj未定義,原因是因為setTimeout方法是window的方法,是個全局方法。執行這個方法的代碼的作用域環境是window。

obj是當初display方法的參數傳進來的,是個局部變量。在window下找不到obj這個變量所以報未定義。

2.method:

在這兒我把method和function區分開了,區別在哪兒呢?代碼如下:

function display(obj)
{
    obj.style.display='none';
    window.setTimeout("fn(obj)", 5000);
}

function fn(o){
    o.style.display='inline'
}


像上面代碼一樣執行,還是會報obj未定義,原因和上面一樣的,這兒調用的fn()是全局方法,它的參數obj在全局變量中找不到。

這個和參數為function的區別在於,method是定義好了方法,當成第一個參數傳過setTimeout(),而function是在第一個參數的位置定義function,兩者有很大的區別,下面會講解。

注意,這兒提醒下,我在寫代碼的時候犯了個錯誤,代碼如下:

function display(obj)
{
   obj.style.diaplay='none';
  window.setTimeout(fn(obj),500);    
}
function fn(0){
   o.style.display='inline';
}

我把fn(obj)的引號去掉了,這樣的寫法是錯誤的,這樣寫,fn會被立即調用,而不是500毫秒之后。

3.function:

function display(obj)
{
   obj.style.diaplay='none';
  window.setTimeout(function(){ obj.style.display='inline';},500);    
}

這種寫法是把function直接寫在了setTimeout的第一個參數位置,這樣寫就和display()形成了一個閉包。所以setTimeout執行function的時候display的作用域是存在的。

這樣就會先去display()的作用域找obj這個變量,obj是當方法的參數傳進來的,所以是能找到的。這樣就能正確的執行這段代碼。

 

總結:

 要解決這種問題又兩個方法,第一:把obj聲明成全局變量,setTimeout是可以調用的。全局變量會一直存在,直到頁面關閉。

 第二種:把setTimeout方法的第一個參數寫成function,這樣形成一個閉包來訪問局部變量。但是閉包會使得它的父函數的變量和方法一直處於內存,直到閉包函數調用結束。

此兩種方法各有優缺點,根據自己的需求來取舍。

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM