-1

在 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函数分配给 object request.onreadystatechange,但我不明白为什么或何时使用这种构造。

例如,使用这种结构而不是做类似的事情有什么好处:

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

另外,这是函数式语言特性的一个例子吗?

4

6 回答 6

1

I'm curious what kind of construction is request.onreadystatechange = displayDetails;. The book says that "this is a reference to a function, not a function call". However I don't understand what this really means.

Essentially this means that your assigning a pre-defined, named function as the event handler for the particular event (in this case readystatechange).

You could also assign an anonymous function depending on your needs:

request.onreadystatechange = function () {
    if (request.readyState == 4) {
        if (request.status == 200) {
            detailDiv = document.getElementById("description");
            detailDiv.innerHTML = request.responseText;
        }
    }
};
于 2013-01-08T18:49:26.710 回答
1

Yes, that's an example of a functional language feature. Functions are first-class citizens on those languages, meaning they can also be passed around, assigned to variables, etc.

About your question on eventhandler = function () { } versus eventhandler = somefunc, you said:

I suppose it assigns the displayDetails function to the object request.onreadystatechange, but I don't understand why or when to use this construction

The request object has a property called onreadystatechange, which represents an event handler function that should be called when the request's readyState property changes. That's why the book said it's not a function call, but a reference assignment. You're not calling the function when you assign it to request.onreadystatechange, it will be called only when that event happens. Clicks and all other events work like that (they're basically asynchronous).

It makes sense to use a function reference instead of an anonymous function assigment if you want to use the same handler for more than one event. For example, if you have two "save" buttons on two different parts of a web page, you can assign the same handler function to their click events.

于 2013-01-08T18:49:43.573 回答
1

You have declared a function called displayDetails. If you ignore the function syntax for a moment, what' you're actually doing is creating an object, almost like var displayDetails = something. When you are assigning the onreadystatechange you are actually assigning a function to it, not a call to the function. This means request.onreadystatechange and function displayDetails()... are the same reference. Calling request.onreadystate() is the same as calling displayDetails().

于 2013-01-08T18:49:50.890 回答
1

The advantage is that you can use displayDetails elsewhere, for example as a onreadystatechange callback for another AJAX request.

If there's only one place where this specific callback is used (which is often the case), it's probably more clear to use an anonymous function expression. That way, you keep the creation and the handling of the request in the same place.

On another note, if the displayDetails function is not nested in another function's scope (such as (function() { ... })(), it will pollute the global scope.

于 2013-01-08T18:49:55.363 回答
1

I suppose it assigns the displayDetails function to the object request.onreadystatechange

Precisely. Functions are first class variables in Javascript and can be passed around and stored in variables, just like objects and numbers. In fact, functions don't really have names and when you access them you are just accessing them via a variable. That is, something like

function f() { }

Is actually kind of syntax sugar for

var f = function(){ }

but I don't understand why or when to use this construction.

Functions serve the same sort of roles as objects (in the object-orientation sense), specially if you close them over some internal state. In cases in an OO language where you would pass something an object with a single doStuff or call method you could instead pass a function instead.

于 2013-01-08T18:52:50.870 回答
1

Your two code examples are equivalent in the terms you are using. A function is sitting somewhere in memory. If we take a reference to that memory location (that address) and store it somewhere, we can run that function from that stored reference. (Note that in Javascript this explanation is more of an analogy that what is really happening. In some languages, its the way it really works.)

In the first bit of code, the reference to the function is stored in something named "displayDetails". That's the global scope variable that is a possible coding issue. But it is valid. Note also that that reference gets copied into "request.onreadystatechange" as well.

In the second bit of code, the reference to the function is stored in "request.onreadystatechange"

Either way, the function gets run when the request is being processed to check whether the result has come back or not.

于 2013-01-08T18:54:13.537 回答