2013-01-08 45 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”

无论哪种方式,函数被当正被处理的请求,以检查结果是否已经回来运行或不。

相关问题