我正在尝试调用 JavaScript 函数,但我无法访问它,因为它显然是 'undefined'

I'm trying to call a JavaScript function but I cannot access it as apparently it is 'undefined'

我正在尝试使用绑定到侦听更改的下拉列表的事件侦听器来调用 JavaScript 函数 (apiCall)。

当从下拉列表中选择不同的菜单项时,我希望函数重新运行,但是当我运行这段代码时,事件侦听器出现错误说'apiCall' 没有定义,尽管它显然就在上面。

有什么建议吗?

提前致谢。

// API CALL 
var request = new XMLHttpRequest()
request.open('GET', base + forecast + key + city, true)

request.onload = function apiCall() {
  var data = JSON.parse(this.response)
  console.log(data)
  string = JSON.stringify(data, null, 4);
  app.innerHTML = string;
}


document.getElementById("locationList").addEventListener("change", apiCall)


//send request
request.send()

先编写函数,然后将其分配给 request.onload 似乎可行:

var request = {};

function apiCall() {
  console.log('hello');
}

request.onload = apiCall;

request.onload();
apiCall();

所以你的代码应该是这样的

// API CALL 
var request = new XMLHttpRequest()
request.open('GET', base + forecast + key + city, true)

function apiCall() { // <- removed 'request.onload' from here...
  var data = JSON.parse(this.response)
  console.log(data)
  string = JSON.stringify(data, null, 4);
  app.innerHTML = string;
}

request.onload = apiCall; // <- and placed it here

const boundApiCall = apiCall.bind(request); // to keep your 'this' object

document.getElementById("locationList").addEventListener("change", boundApiCall)


//send request
request.send()

编辑:我看到您在函数中使用了 this。我不是 100% 确定(仍在此处学习),但我认为我添加的额外 bind 将使您的 this 像以前一样工作。

您分配给 window.onload 的函数是函数 expression,而不是函数 declaration。命名函数表达式的名称不会添加到周围的作用域中,因此,它只能在函数表达式本身的本地使用。这意味着您以后将无法在函数外引用它:

function iAmAFunctionDeclaration() {
  console.log("abc");
}

+function iAmAFunctionExpression() {
  console.log("abc");
}

console.log(typeof iAmAFunctionDeclaration);
console.log(typeof iAmAFunctionExpression); // undefined (not added to the `window`).

相反,如果您可以 apiCall 一个函数声明,您将能够访问它的名称以便稍后执行它,以及将其分配为回调:

function apiCall() {
  console.log("performing api call");
}

window.onload = apiCall;
document.addEventListener("click", apiCall);

为了使您的 API 调用正常工作,您可以 .bind() 您的 requestapiCall 函数,如 @Stratubas or you can replace this keyword with request. This will allow you to handle what this refers to within your callback. For more ways of dealing with this inside of a callback, see this answer and this answer 所示。

您可以阅读有关函数表达式的更多信息here