2012-07-18 28 views
2

我有以下代碼:變量如何在Javascript中工作? setTimeout期間變量值是否可以改變?

function Notification(type) 
{ 
    switch (type) 
    { 
     case "success": 
      notificationID="not1"; 
      break; 
     case "error": 
      notificationID="not2"; 
      break; 
    } 

    setNotificationTimeoutId = setTimeout(function() { 
     jQuery('#' + notificationID).fadeOut(200, function() { 
      var notification = document.getElementById(notificationID); 
      if (notification) 
      { 
       jQuery(notification.parentNode).remove(); 

       if (type == "success") 
         DoSomething(); 
      } 

      setNotificationTimeoutId = null; 
     }); 
    }, 5000); 
} 

我的問題是,如果函數(通知)被調用上的click事件,如果它被調用兩次(第一次用通知(「成功」),然後用通知(「錯誤」))通過兩個單擊事件,是否有可能第二個函數調用更改第一個函數調用的類型變量值?

例如:當第一個調用(成功的一個)在setTimeout內部進入函數時(第二次調用Notification已經用type =「error」進行),它甚至將變量'type'看作「error」雖然這個調用是第一個,它調用類型=「成功」?

+0

不,這是不可能的,應該有另一種伎倆 – haynar 2012-07-18 11:53:55

+0

是的,它是可能的,其實這就是在你的代碼已經在發生了。要改變它,在函數的開頭添加'var notificationID;'。 – davin 2012-07-18 11:55:05

回答

2

如果函數Notification被調用上的click事件,如果得到由兩個click事件調用兩次(第一次用Notification("success")然後用Notification("error")),是第二個函數調用可能會更改第一個函數調用的變量值type

編號type變量是一個參數,因此它是與您的函數綁定的。它的值在隨後的調用中不會改變,每個函數調用都會創建該變量的一個新實例,並且無法訪問其他實例。

你的匿名函數的超時範圍是「subscope」Notification的一個,所以它總是會訪問正確的type變量。

但是您的notificationID是一個全局變量(不是本地範圍的),並且所有對所有超時的調用Notification的所有調用都將使用相同的變量實例。因此,第二次調用Notification會在第一次訪問超時之前更改它。要解決此問題,請添加var關鍵字。

clearTimeout(setNotificationTimeoutId); 
+0

謝謝你的答案,這是我尋找的答案類型。在我真正的代碼,notificationId是地方太:) – Fazi 2012-07-18 12:07:51

+0

我不想以清除任何活動超時,因爲我想多一個定時器,在同一時間 – Fazi 2012-07-18 12:25:38

+0

OK運行,這僅僅是一個猜測... – Bergi 2012-07-18 12:26:57

1

您應該本地化您的notificationID變量,因爲它是全局變量,允許函數第二次運行以更改第一次運行時的輸出。

使用VAR本地化:

var notificationID; 

switch (type) 
{ 
    case "success": 
     notificationID="not1"; 
     break; 
    case "error": 
     notificationID="not2"; 
     break; 
} 
+0

我的興趣在於變量類型,正如我所提到的。 notificationId在這裏是全球性的,但是在我的代碼中它是本地的,我只是不想複製粘貼整個代碼。Sry如果我推動你誤解 – Fazi 2012-07-18 12:06:19

0

或者,如setNotificationTimeoutId也是一個外部範圍,可以從兩個電話訪問,你可以(?應該)創造了新的,通過添加以下行之前清除任何活動超時

這對你有用嗎? http://jsfiddle.net/gRoberts/vgSGL/

不用setTimeout,你可以使用jQuery的延遲方法,它類似。

希望它有幫助嗎?

GAV株系