2013-01-08 44 views
-1

頭首先阿賈克斯,他們給了下面的例子:引用函數(例如,在Javascript中)意味着什麼?

function getDetails(itemName) { 
    request = createRequest(); 
    if (request == null) { 
    alert("Unable to create request"); 
    return; 
    } 
    var url= "getDetails.php?ImageID=" + escape(itemName); 
    request.open("GET", url, true); 
    request.onreadystatechange = displayDetails;//This references the function below 
    request.send(null); 
} 

function displayDetails() { 
    if (request.readyState == 4) { 
    if (request.status == 200) { 
     detailDiv = document.getElementById("description"); 
     detailDiv.innerHTML = request.responseText; 
    } 
    } 
} 

我很好奇,什麼樣的建築是request.onreadystatechange = displayDetails;。這本書說,「這是一個函數的引用,而不是函數調用」。不過我不明白這個真是的意思。我想它會將displayDetails函數賦值給對象request.onreadystatechange,但我不明白爲什麼或何時使用這種構造。

例如,什麼是使用這種結構,而不是做類似的優勢:

request.onreadystatechange = function() { 
    if (request.readyState == 4) { 
    if (request.status == 200) { 
     detailDiv = document.getElementById("description"); 
     detailDiv.innerHTML = request.responseText; 
    } 
    } 
} 

而且,是一個功能性的語言特性的一個例子嗎?

+2

老實說,發佈的第一個代碼塊是sl as的,因爲它污染了全球範圍。使用命名函數進行回調的原因是,您還需要在別處明確調用該函數。 – Shmiddty

+2

問題的標題說的是Javascript,但是在您說'Head First Java'的問題中。代碼看起來像Javascript,而不是Java。那是對的嗎? – shargors

+0

IMO它保持乾淨。雖然上面的人說這個例子有點sl。。你還知道當你寫'request.onreadystatechange = function(){...}'時,你實際上正在分配'anonymous' javascript函數的_reference_嗎? –

回答

1

是的,這是一個功能性的語言特性的一個例子。功能在這些語言的一等公民,這意味着它們也可以被傳來傳去,賦值給變量等

關於eventhandler = function() { }eventhandler = somefunc你的問題,你說:

我想它分配displayDetails函數對象request.onreadystatechange,但我不明白爲什麼或者何時使用這種結構

request對象有一個屬性叫做onreadystatechange,它代表一個事件處理程序當請求的readyState屬性更改時應該調用該函數。這就是爲什麼這本書說這不是一個函數調用,而是一個參考作業。當您將它分配給request.onreadystatechange時,您不會調用該函數,只有在發生該事件時纔會調用該函數。點擊和所有其他事件的工作就是這樣(他們基本上是異步)。

如果您想爲多個事件使用相同的處理程序,那麼使用函數引用而不是匿名函數分配是有意義的。例如,如果在網頁的兩個不同部分上有兩個「保存」按鈕,則可以爲其單擊事件分配相同的處理函數。

1

我很好奇request.onreadystatechange = displayDetails ;.這本書說,「這是一個函數的引用,而不是函數調用」。但我不明白這是什麼意思。

本質上,這意味着您將一個預定義的命名函數指定爲特定事件(本例中爲readystatechange)的事件處理函數。

你也可以根據自己的需要分配一個匿名函數:

request.onreadystatechange = function() { 
    if (request.readyState == 4) { 
     if (request.status == 200) { 
      detailDiv = document.getElementById("description"); 
      detailDiv.innerHTML = request.responseText; 
     } 
    } 
}; 
1

您已經聲明瞭一個名爲displayDetails的函數。如果你暫時忽略function語法,你實際上在做什麼是創建一個對象,就像var displayDetails = something。當您分配onreadystatechange時,您實際上正在爲其分配功能,而不是調用的功能。這意味着request.onreadystatechangefunction displayDetails()...是相同的參考。致電request.onreadystate()與致電displayDetails()相同。

1

好處是您可以在其他地方使用displayDetails,例如作爲另一個AJAX請求的onreadystatechange回調。

如果只有一個地方使用了特定的回調(通常是這種情況),那麼使用匿名函數表達式可能會更清楚。這樣,您就可以將創建和處理請求保留在同一個地方。

在另一方面,如果沒有嵌套在displayDetails功能在另一個函數的範圍(如(function() { ... })(),它會污染全局範圍。

+0

「污染全球範圍」意味着什麼? – JDelage

+0

當您用相當常見的名稱創建大量全局變量(或函數)時,其中一個與其他腳本,插件或庫中的名稱衝突的可能性更大。將局部變量和函數保留在全局範圍之外(即在函數範圍內)並且僅暴露需要從外部訪問的變量和函數是一種很好的做法。即使這樣,通過將所有導出的東西保存在一個名稱空間中,您也可以減少污染。 'myplugin.coolFunction()'而不是'coolFunction()'。 –

1

我想它的displayDetails函數分配給該對象request.onreadystatechange

準確地說,函數是在Javascript第一類變量和可以被傳遞並存儲在變量,就像對象和數字。其實,功能真的沒有名字,當你訪問他們,你只是訪問他們通過一個變種iable。也就是說,像

function f() { } 

實際上是一種語法糖

var f = function(){ } 

,但我不明白爲什麼或者何時使用這種結構。

函數提供與對象(面向對象方向)相同的角色,特別是如果您通過某些內部狀態關閉它們。在使用OO語言的情況下,您可以使用單個doStuffcall方法將某個對象傳遞給某個對象,您可以改爲傳遞一個函數。

1

您的兩個代碼示例與您使用的術語相同。一個函數坐在內存中的某處。如果我們對該內存位置(該地址)進行引用並將其存儲在某處,則可以從該存儲的引用運行該函數。 (請注意,在Javascript中,這種解釋更類似於真正發生的事情,在某些語言中,它的實際工作方式)

在第一位代碼中,對函數的引用存儲在某個命名爲「displayDetails」。這是全球範圍變量,這是一個可能的編碼問題。但它是有效的。還要注意,該引用也被複制到「request.onreadystatechange」中。

在代碼的第二位,所述參考函數存儲在「request.onreadystatechange」

無論哪種方式,函數被當正被處理的請求,以檢查結果是否已經回來運行或不。

相關問題