Uncaught TypeError when invoking callbacks

时间:2018-01-15 18:13:46

标签: javascript ajax xmlhttprequest onreadystatechange

I had an error that I have managed to fix on my own. Can someone please explain to me why my code wasn’t working and the mechanics of what caused it.

Code is included below:

var listTables = function (tables) {
  console.log(tables);
}

var ajaxReq = function (success_cb, url) {
  // success_cb can be invoked here without errors
  var http = new XMLHttpRequest();
  http.onreadystatechange = function (success_cb) {
    if (this.readyState == 4 && this.status == 200) {
      success_cb(this); // Uncaught TypeError: success_cb is not a function
    }
  }
  http.open("GET", url, true);
  http.send();
}
ajaxReq(listTables, "http://www.someurl.com");

When I remove the success_cb callback from the onreadystatechange function definition the code works fine. Is this an issue that is related to scope?

1 个答案:

答案 0 :(得分:1)

错误是您在内部函数中重复success_cb作为参数:

var ajaxReq = function (success_cb, url) { // First time success_cb parameter is used: correct.
  var http = new XMLHttpRequest();
  http.onreadystatechange = function (success_cb) { // Second time: wrong!
    // ...
  }
  // ...
}

这有两个意外的事情:

  • 它掩盖了您原来的(第一个)success_cb,因此无法再访问
  • 而是将readystatechange事件的事件参数分配给success_cb,这是一个对象

Overshadowing”表示提供的名称相同的变量(或参数)的范围更接近。

所以只需删除第二种用法:

var listTables = function (tables) {
  console.log(tables);
}

var ajaxReq = function (success_cb, url) {
  // success_cb can be invoked here without errors
  var http = new XMLHttpRequest();
  http.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {
      success_cb(this);
    }
  }
  http.open("GET", url, true);
  http.send();
}
ajaxReq(listTables, "http://www.someurl.com");