在 JavaScript 中,this 的指向取決於函數如何被調用,而非定義位置。理解「方法調用模式」與「函數調用模式」的區別,是避免 this 指向錯誤的關鍵。本文通過代碼示例深度解析兩種模式的行為差異。
| 調用模式 | 調用形式 | this 指向 | 典型場景 |
|---|---|---|---|
| 方法調用模式 | obj.method() |
調用該方法的對象(obj) |
對象原型方法、類實例方法 |
| 函數調用模式 | func() |
全局對象(瀏覽器中為 window,嚴格模式為 undefined) |
獨立函數、回調函數、IIFE |
var doubling = function(x) {
return x * 2;
};
var obj = {
val: 100,
// 屬性初始化時立即執行的匿名函數 —— 函數調用模式
prop: (function() {
var that = this; // this 指向 window!
console.log('prop 初始化:', that, typeof that); // [object Window] object
return doubling(that.val); // window.val 為 undefined → NaN
})(),
// 普通方法 —— 方法調用模式
get_prop: function() {
var that = this; // this 指向 obj
console.log('get_prop 調用:', that, typeof that); // [object Object] object
return doubling(that.val); // 正確返回 200
}
};
// 測試
console.log('obj.prop:', obj.prop); // NaN
console.log('obj.get_prop():', obj.get_prop()); // 200
prop 使用 IIFE(立即調用函數表達式) 初始化。雖然它寫在對象字面量內部,但調用形式是 (function(){...})() —— 純粹的函數調用,this 綁定到全局對象 window。此時 that.val 實際訪問的是 window.val(未定義),導致 doubling 返回 NaN。
get_prop 是標準方法定義,調用時用 obj.get_prop(),符合方法調用模式,this 正確指向 obj,that.val 取到 100,最終返回 200。
// 對象創建後動態添加
obj.new_prop = (function() {
return doubling(this.val); // 函數調用模式 → this 仍是 window
})();
obj.new_get_prop = function() {
return doubling(this.val); // 方法調用模式 → this 是 obj
};
console.log(obj.new_prop); // NaN
console.log(obj.new_get_prop()); // 200
結論一致:只有通過「對象.方法()」形式調用,this 才指向該對象。
this,捕獲外層詞法作用域的 thisthisself:經典變量緩存法(如示例所示)this 的 IIFE.bind(this) 或箭頭函數'use strict'),函數調用模式下 this 為 undefined,能更早暴露問題