首頁  >  文章  >  web前端  >  JavaScript 中的 &#this&# 關鍵字、call()、apply() 和 bind() 方法 - 簡單解釋

JavaScript 中的 &#this&# 關鍵字、call()、apply() 和 bind() 方法 - 簡單解釋

Barbara Streisand
Barbara Streisand原創
2024-09-24 06:18:01932瀏覽

學習 call()、apply() 和 bind() 方法很重要,因為它們允許您在 JavaScript 中控制 this 的上下文。在預設情況下此行為無法如預期運作的情況下,例如從一個物件借用方法到另一個物件或在回呼內維護正確的上下文時,這些方法提供了靈活性和控制。透過掌握它們,您可以編寫更有效率、可重複使用和上下文感知的函數,這在複雜的應用程式中特別有用。

在我們進入 call()、apply() 和 bind() 方法之前,讓我們先了解一下「this」關鍵字及其機制。

‘這個’關鍵字

讓我們透過以下要點來了解此關鍵字的意思:

  • 在物件方法中, this 指的是物件。在物件內定義的方法內,this 將指向擁有該方法的物件。

  • 在常規函數中, this 指的是全域物件。在非嚴格模式下,如果在全域上下文中呼叫函數(不是作為物件的方法),則 this 會引用全域物件(瀏覽器中的視窗)。

  • 在嚴格模式函數中, 這是未定義的。如果該函數不是物件的方法且未綁定到特定上下文(透過呼叫、應用或綁定),則 this 在嚴格模式下將是未定義的。

  • 在事件處理程序中, 這是指接收事件的元素。當事件被觸發時,這是指呼叫該事件的 HTML 元素。

    <button onclick="this.style.display='none'">
      Click to Remove Me!
    </button>
    

    在本例中,this 指的是接收 onclick 事件的按鈕元素本身。

在箭頭函數中, 其行為有所不同。箭頭函數沒有自己的 this 上下文。相反,這是在創建箭頭函數時從詞法上繼承自周圍範圍的。這表示箭頭函數內的 this 將引用其封閉函數或上下文的 this 值。

const person = {
  name: "Alice",
  greet: function() {
    setTimeout(() => {
      console.log(`Hi, I'm ${this.name}`);
    }, 1000);
  }
};

person.greet(); // Output: Hi, I'm Alice

在這種情況下,setTimeout 中的箭頭函數繼承自greet 方法,該方法指向person 物件。

呼叫()方法

call() 方法可讓您從一個物件「借用」函數或方法,並透過將另一個物件作為第一個參數傳遞來將其與另一個物件一起使用。第一個參數成為函數內的 this 值,後面跟著其他參數。

call() 方法不會建立新函數;它使用提供的上下文和參數來運行現有函數。

const person = {
  fullName: function(city, country) {
    console.log(this.firstName + " " + this.lastName + " is going to " + city + ", " + country + ".");
  }
}

const person1 = {
  firstName: "John",
  lastName: "Doe"
}

person.fullName.call(person1, "Oslo", "Norway");
// Output: John Doe is going to Oslo, Norway.

在此範例中,call() 用於執行具有 person1 資料(firstName 和 lastName)的 person 的 fullName 方法,附加參數為「Oslo」和「Norway」。

apply() 方法

apply() 方法與 call() 方法非常相似。主要區別在於如何將參數傳遞給函數。使用 apply(),您可以將參數作為數組(或類似數組的物件)傳遞,而不是單獨傳遞。

與 call() 一樣,apply() 方法不會建立新函數。它立即使用提供的上下文(此值)和參數執行函數。

const person = {
  fullName: function(city, country) {
    console.log(this.firstName + " " + this.lastName + " is going to " + city + ", " + country + ".");
  }
}

const person1 = {
  firstName: "John",
  lastName: "Doe"
}

person.fullName.apply(person1, ["Oslo", "Norway"]);
// Output: John Doe is going to Oslo, Norway.

在此範例中,apply() 用於呼叫 person 物件的 fullName 方法,但使用 person1 的上下文 (this)。參數“Oslo”和“Norway”作為數組傳遞。

綁定()方法

JavaScript中的bind()方法可以讓你為函數或方法設定上下文(this值),就像call()和apply()一樣。然而,與 call() 和 apply() 不同,bind() 方法不會立即呼叫該函數。相反,它會傳回一個新函數,並將 this 值設定為您指定的物件。

const person = {
  fullName: function(city, country) {
    console.log(this.firstName + " " + this.lastName + " is going to " + city + ", " + country + ".");
  }
}

const person1 = {
  firstName: "John",
  lastName: "Doe"
}

const func = person.fullName.bind(person1);
func("Oslo", "Norway");
// Output: John Doe is going to Oslo, Norway.

在此範例中,bind() 建立一個新函數 func,並將 this 值設為 person1。該函數不會立即調用,但您可以稍後調用它,傳入參數“Oslo”和“Norway”。

範例:具有多個上下文的集中式記錄器

這是一個小而複雜的應用程式範例,其中使用call()、apply() 或bind() 可以提高效率,尤其是在處理用於日誌記錄的函數的部分應用時:

假設您有一個集中式日誌記錄功能,可以記錄不同使用者執行操作的資訊。使用bind()可以讓你有效地為不同的使用者設定this上下文,避免重複的程式碼。

const logger = {
  logAction: function(action) {
    console.log(`${this.name} (ID: ${this.id}) performed: ${action}`);
  }
};

const user1 = { name: "Alice", id: 101 };
const user2 = { name: "Bob", id: 202 };

// Create new logger functions for different users
const logForUser1 = logger.logAction.bind(user1);
const logForUser2 = logger.logAction.bind(user2);

// Perform actions without manually passing user context
logForUser1("login");
// Output: Alice (ID: 101) performed: login

logForUser2("purchase");
// Output: Bob (ID: 202) performed: purchase

為什麼它有效:

上下文重複使用:您不需要在每次記錄操作時手動傳遞使用者上下文。上下文(this)綁定一次,日誌記錄就變得可重複使用且乾淨。

模組化:如果您需要添加更多使用者或操作,您可以快速將它們綁定到記錄器,而無需更改函數本身,從而保持程式碼乾燥(不要重複)。

以上是JavaScript 中的 &#this&# 關鍵字、call()、apply() 和 bind() 方法 - 簡單解釋的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn