【问题标题】:I'm trying to call a JavaScript function but I cannot access it as apparently it is 'undefined'我正在尝试调用 JavaScript 函数,但我无法访问它,因为它显然是“未定义”
【发布时间】:2020-01-20 03:00:59
【问题描述】:

我正在尝试使用绑定到下拉列表的事件侦听器调用 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()

【问题讨论】:

  • 将函数分配给 XMLHttpRequest 的 request.onload 属性与定义具有适当范围的函数不同。
  • 使函数匿名request.onload = function(e) {...}

标签: javascript function methods addeventlistener event-listener


【解决方案1】:

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

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() 您的 request 转换为您的 apiCall 函数,如 @Stratubas 所示,或者您可以将 this 关键字替换为 request。这将允许您处理回调中 this 所指的内容。有关在回调中处理this 的更多方法,请参阅this answerthis answer

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

【讨论】:

  • OP 的代码有一个this.response。它会与您的代码一起正常工作吗?
  • @Stratubas 嗨,感谢您指出这一点。我没有注意到回调中使用了this。我已经添加了一个关于现在处理它的注释。干杯
【解决方案2】:

先编写函数,然后将其分配给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 像以前一样工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-29
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多