首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

IE 下 AJAX 回呼函式 this 指向陷阱:全域物件 vs XHR 物件

     編輯:更多程式設計知識

封裝跨瀏覽器 AJAX 元件時,最隱蔽的坑在於 onreadystatechange 回呼函式的 this 指向差異:標準瀏覽器指向 XMLHttpRequest 實例,IE 6/7 卻指向 window 全域物件。本文詳細重現問題、診斷過程與解決方案。

問題重現

var Ajax = {
  xhr: null,
  callback: null,
  connect: function(params) {
    this.xhr = this.createXHR();
    this.callback = params.callback;
    this.xhr.onreadystatechange = this.response; // 直接指派方法
    this.xhr.open(params.method, params.url, true);
    this.xhr.send(params.data);
  },
  response: function() {
    // 標準瀏覽器 this === this.xhr
    // IE 6/7   this === window
    if (this.readyState === 4) { ... }
  }
};

在 IE 下,this.readyState 讀取 window.readyState(undefined),條件判斷失效,回呼永不執行,且無任何錯誤訊息。

診斷關鍵步驟

  1. 在 response 內插入 alert(this instanceof Object):IE 回傳 false,證明 this 非物件。
  2. 插入 alert(this === window):IE 回傳 true,確認指向全域物件。

根本原因

IE 將 onreadystatechange 視為全域事件處理器,以 window 為執行上下文呼叫;標準瀏覽器依 DOM Level 2 Events 規範,以事件目標(XHR 物件)為 this。

三種解決方案

1. 閉包捕獲 XHR 實例(推薦,最穩健)

connect: function(params) {
  var xhr = this.createXHR();
  var self = this;
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) self.callback(xhr.responseText);
      else self.callback(null, xhr.status);
    }
  };
  ...
}

2. 使用 Function.prototype.bind (ES5,需 polyfill)

xhr.onreadystatechange = this.response.bind(this); // this 鎖定為 Ajax 物件
// 但 response 內仍需用 Ajax.xhr 而非 this.xhr

3. 統一使用 Ajax.xhr 而非 this(最簡單)

response: function() {
  if (Ajax.xhr.readyState === 4) { ... }
}

現代最佳實踐

放棄手寫 XHR 封裝,改用 fetch + Promise 或成熟庫:

// fetch 範例
fetch(url, { method: 'POST', body: data })
  .then(r => r.json())
  .then(data => callback(data))
  .catch(err => callback(null, err));
  • 原生 Promise 鏈結天然解決 this 指向問題。
  • 支援中斷、超時、串流處理等進階功能。
  • IE 需引入 whatwg-fetch 與 promise-polyfill。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved