You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套XMLHttpRequest中this指向异常及原理解析求助

XMLHttpRequest嵌套请求中this指向异常的原因解析

核心问题1:错误地把函数执行结果赋值给了onload

看你代码里这一行:

reqObj.onload = buildProjects(reqObj, obj);

这里不是把buildProjects函数引用赋值给onload事件,而是直接执行了buildProjects函数,把它的返回值(因为函数没写return,实际是undefined)赋值给了onload。

这时候buildProjects是在全局作用域下直接调用的,非严格模式下this默认指向window,这就是为什么你拿到的是window而不是XHR对象。

而你单个请求时写的reqObj.onload = reqListener;是正确的——把函数引用给事件,当请求完成时,XHR对象会作为调用者去执行这个函数,此时this才会指向该XHR实例。

核心问题2:传递参数无效的原因

因为你直接执行了buildProjects,此时XHR请求还没发送完成,reqObj.responseText根本没有内容,所以你传递的reqObj虽然是正确的实例,但里面的响应数据是空的,自然达不到预期效果。

为什么单个请求时this正常?

JavaScript里this的指向完全由函数的调用方式决定:

  • 当函数作为某个对象的方法被调用时(比如XHR对象触发onload时调用你的函数),this指向这个对象。
  • 当函数被直接调用(比如fn()),非严格模式下this绑定到window,严格模式下是undefined。

你的单个请求场景中,reqListener是被XHR对象调用的,所以this指向XHR;而嵌套场景里,buildProjects是你手动直接调用的,所以this指向window。

为什么bind能解决问题?

bind()方法会创建一个新的绑定函数,这个函数被调用时,this会固定指向你传入的对象(比如reqObj.bind(reqObj)),同时还能预先传递你需要的参数(比如obj)。当XHR请求完成触发onload时,调用的是这个绑定后的函数,this就会指向你指定的XHR实例,参数也能正确传递。

给你改个正确的写法示例:

function reqListener() {
    var obj = JSON.parse(this.responseText)
    var reqObj = new XMLHttpRequest();
    // 用bind绑定this为reqObj,同时预先传入obj参数
    reqObj.onload = buildProjects.bind(reqObj, obj);
    reqObj.open("get", "post_box.html", true);
    reqObj.send();
}

function buildProjects(data) {
    // 这里的this就是绑定的reqObj
    console.log("data is: " + data.title);
    console.log("State: " + this.readyState);
    console.log("Response is: " + this.responseText);
}

内容的提问来源于stack exchange,提问作者DevJoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 21:52:34