引用函数(例如,在Javascript中)是什么意思?

时间:2013-01-08 18:44:14

标签: javascript

在Head First Ajax中,他们给出了以下示例:

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;
    }
  }
}

另外,这是功能语言功能的一个例子吗?

6 个答案:

答案 0 :(得分: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 :(得分:1)

是的,这是功能语言功能的一个例子。函数是这些语言的一等公民,这意味着它们也可以被传递,分配给变量等等。

关于eventhandler = function () { }eventhandler = somefunc的问题,您说:

  

我想它会将displayDetails函数分配给对象request.onreadystatechange,但我不明白为什么或何时使用这种结构

request对象有一个名为onreadystatechange的属性,它表示在请求的readyState属性更改时应调用的事件处理函数。这就是为什么这本书说它不是函数调用,而是参考赋值。当您将该函数分配给request.onreadystatechange时,您不会调用该函数,只有在该事件发生时才会调用该函数。点击和所有其他事件都是这样的(它们基本上是异步)。

如果要对多个事件使用相同的处理程序,则使用函数引用而不是匿名函数分配是有意义的。例如,如果在网页的两个不同部分有两个“保存”按钮,则可以为其单击事件分配相同的处理函数。

答案 2 :(得分:1)

您已声明了一个名为displayDetails的函数。如果您暂时忽略function语法,那么您实际在做的是创建一个对象,就像var displayDetails = something一样。在分配onreadystatechange时,您实际上正在为其分配一个功能,而不是调用该功能。这意味着request.onreadystatechangefunction displayDetails()...是相同的参考。致电request.onreadystate()与致电displayDetails()相同。

答案 3 :(得分:1)

优点是你可以在其他地方使用displayDetails,例如作为另一个AJAX请求的onreadystatechange回调。

如果只有一个地方使用了这个特定的回调(通常就是这种情况),那么使用匿名函数表达式可能会更加明确。这样,您就可以在同一个地方保留请求的创建和处理。

另一方面,如果displayDetails函数没有嵌套在另一个函数的作用域中(例如(function() { ... })()),它将污染全局作用域。

答案 4 :(得分:1)

  

我想它会将displayDetails函数分配给对象request.onreadystatechange

正。函数是Javascript中的第一类变量,可以传递并存储在变量中,就像对象和数字一样。实际上,函数实际上没有名称,当您访问它们时,您只是通过变量访问它们。就是这样的事情

function f() { }

实际上是

的语法糖
var f = function(){ }
  

但我不明白为什么或何时使用这种结构。

函数提供与对象相同的角色(在面向对象的意义上),特别是如果您在某个内部状态上关闭它们。如果您在OO语言中使用单doStuffcall方法传递某个对象,则可以改为传递函数。

答案 5 :(得分:1)

您的两个代码示例在您使用的术语中是等效的。函数位于内存中的某个位置。如果我们引用该内存位置(该地址)并将其存储在某处,我们可以从该存储的引用中运行该函数。 (请注意,在Javascript中,这种解释更类似于真正发生的事情。在某些语言中,它的实际运作方式。)

在代码的第一位,对函数的引用存储在名为“displayDetails”的内容中。这是可能的编码问题的全局范围变量。但它是有效的。另请注意,该引用也会被复制到“request.onreadystatechange”中。

在第二位代码中,对函数的引用存储在“request.onreadystatechange”

无论哪种方式,函数都会在处理请求时运行,以检查结果是否已经返回。