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

PHP 方法調用模式與函數調用模式的 this 綁定差異詳解

     編輯:PHP 綜合知識

JavaScript 中 this 綁定機制:方法調用 vs 函數調用

在 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

關鍵點解析

1. 屬性初始化階段的「函數調用模式」

prop 使用 IIFE(立即調用函數表達式) 初始化。雖然它寫在對象字面量內部,但調用形式是 (function(){...})() —— 純粹的函數調用,this 綁定到全局對象 window。此時 that.val 實際訪問的是 window.val(未定義),導致 doubling 返回 NaN。

2. 方法調用時的正確綁定

get_prop 是標準方法定義,調用時用 obj.get_prop(),符合方法調用模式,this 正確指向 obj,that.val 取到 100,最終返回 200。

3. 對象字面量外的動態添加

// 對象創建後動態添加
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,捕獲外層詞法作用域的 this
  • bind/call/apply:顯式綁定 this
  • const that = this / self:經典變量緩存法(如示例所示)

最佳實踐建議

  1. 對象字面量初始化屬性時,避免使用依賴 this 的 IIFE
  2. 回調函數傳遞前使用 .bind(this) 或箭頭函數
  3. 啟用 ES5 嚴格模式('use strict'),函數調用模式下 this 為 undefined,能更早暴露問題
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved