」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > JavaScript 中的 &#this&# 關鍵字、call()、apply() 和 bind() 方法 - 簡單解釋

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

發佈於2024-10-31
瀏覽:458

学习 call()、apply() 和 bind() 方法很重要,因为它们允许您在 JavaScript 中控制 this 的上下文。在默认情况下此行为无法按预期工作的情况下,例如从一个对象借用方法到另一个对象或在回调内维护正确的上下文时,这些方法提供了灵活性和控制。通过掌握它们,您可以编写更高效、可重用和上下文感知的函数,这在复杂的应用程序中特别有用。

在我们进入call()、apply()和bind()方法之前,让我们先了解一下“this”关键字及其机制。

‘这个’关键字

让我们通过以下要点了解此关键字何时以及所指的内容:

  • 在对象方法中, this 指的是对象。在对象内定义的方法内,this 将指向拥有该方法的对象。

  • 在常规函数中, this 指的是全局对象。在非严格模式下,如果在全局上下文中调用函数(不是作为对象的方法),则 this 引用全局对象(浏览器中的窗口)。

  • 在严格模式函数中, this 是未定义的。如果函数不是对象的方法并且未绑定到特定上下文(通过调用、应用或绑定),则 this 在严格模式下将是未定义的。

  • 在事件处理程序中, 这是指接收事件的元素。当事件被触发时,它指的是调用该事件的 HTML 元素。

    
    

    在本例中,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方法的this,它指向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)被绑定一次,日志记录变得可重用且干净。

模块化:如果您需要添加更多用户或操作,您可以快速将它们绑定到记录器,而无需更改功能本身,从而保持代码 DRY(不要重复自己)。

版本聲明 本文轉載於:https://dev.to/abeertech01/this-keyword-call-apply-and-bind-methods-in-javascript-simply-explained-3ag2?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何將 Firebase 與 Laravel 集成
    如何將 Firebase 與 Laravel 集成
    Laravel and Firebase are two powerful tools that can significantly enhance the development of modern web applications. Laravel, a popular PHP framewor...
    程式設計 發佈於2024-11-07
  • Expo with Redux Toolkit、檔案系統與 Redux Persist:綜合指南
    Expo with Redux Toolkit、檔案系統與 Redux Persist:綜合指南
    Redux Toolkit 是一個流行的函式庫,它透過提供一組實用程式和約定來簡化 Redux 開發。它包括一個減速器和動作創建模式,可以簡化編寫 Redux 邏輯的過程。將 Redux Persist 與 Redux Toolkit 結合可以顯著提高 React Native 應用程式中狀態管理的...
    程式設計 發佈於2024-11-07
  • 如何處理非巢狀 Lambda 閉包中的變數作用域問題?
    如何處理非巢狀 Lambda 閉包中的變數作用域問題?
    Python Lambda 閉包作用域問題將變數封裝在閉包中以將其從函數簽章中刪除是一種常用於高效代碼結構的技術。但是,在非嵌套 lambda 的情況下,閉包保留變數的最終值,從而在嘗試基於迭代變數存取特定值時導致問題。 考慮提供的程式碼片段:names = ['a', 'b', 'c'] def ...
    程式設計 發佈於2024-11-07
  • 如何使用現代 CSS 將按鈕無縫整合到輸入欄位中?
    如何使用現代 CSS 將按鈕無縫整合到輸入欄位中?
    如何使用現代CSS 將按鈕整合到輸入中問題:創建視覺元素其中按鈕無縫整合在輸入欄位中,允許正常的使用者互動、保留文字可見性並保持可存取性和螢幕閱讀器相容性。 解決方案:Flexbox 和表單邊框最佳方法是使用彈性盒佈局以及包含元素(表單)上的邊框:定位:設定具有水平行佈局的彈性盒,允許輸入擴展以填充...
    程式設計 發佈於2024-11-07
  • 核心開發中的 C++:綜合指南
    核心開發中的 C++:綜合指南
    介紹 由於直接硬體存取和最小的運行時開銷,核心開發傳統上是 C 的領域。然而,由於其物件導向的特性,C 在核心程式設計中找到了自己的位置,這可以帶來更乾淨、更易於維護的程式碼。本指南將逐步介紹如何使用 C 進行核心開發,重點是設定環境、建置專案以及使用 C 功能編寫核心程式碼,同時...
    程式設計 發佈於2024-11-07
  • 在 React 專案中實作 CSS 模組
    在 React 專案中實作 CSS 模組
    React 中的 CSS 模組是一種透過自動產生唯一類別名稱來確定 CSS 範圍的方法。這可以防止大型應用程式中的類別名稱衝突並允許模組化樣式。以下是如何在 React 專案中使用 CSS 模組: 1. 設定 預設情況下,React 支援 CSS 模組。您只需使用擴展名 .modul...
    程式設計 發佈於2024-11-07
  • 有哪些資源可用於實現彗星模式?
    有哪些資源可用於實現彗星模式?
    Comet:伺服器推送模式伺服器推送是一種在伺服器和Web 用戶端之間實現雙向通訊的技術,已經獲得了顯著的成果最近的興趣。 Comet 設計模式是作為在 JavaScript 應用程式中實現伺服器推送的一種有前途的方法而出現。本問題探討了 Comet 模式的 jQuery 實作和通用資源的可用性。 ...
    程式設計 發佈於2024-11-07
  • 探索心理健康門診計畫的類型
    探索心理健康門診計畫的類型
    門診心理健康治療方法是一種不強調在醫療機構過夜的方案。這種療法主要在醫生辦公室、醫院或診所提供,在那裡人們可以進行定期治療,以進行高度結構化的定期治療。 在 COVID-19 大流行期間,全球約有 2.75 億名吸毒者。比前幾十年高出近 22%。吸毒成癮的增加導致全美吸毒過量人數創下歷史新高。好消...
    程式設計 發佈於2024-11-07
  • 如何在 C++ Builder 中初始化 OpenGL 幀:逐步指南
    如何在 C++ Builder 中初始化 OpenGL 幀:逐步指南
    如何在C Builder 中初始化OpenGL 幀在C Builder 中的窗體內初始化OpenGL 幀可能是一項具有挑戰性的任務。在嘗試調整現有 OpenGL 程式碼(例如問題中提供的範例)時,您可能會遇到困難。 要正確建立和渲染OpenGL 幀,請依照下列步驟操作:使用TForm::Handle...
    程式設計 發佈於2024-11-07
  • 利用這些罕見的 HTML 屬性來增強您的 Web 開發技能
    利用這些罕見的 HTML 屬性來增強您的 Web 開發技能
    Introduction HTML attributes are most often referred to as the overlooked heroes of web development, playing a crucial role in shaping the st...
    程式設計 發佈於2024-11-07
  • 如何在 Python 中將字串轉換為二進位:ASCII 與 Unicode?
    如何在 Python 中將字串轉換為二進位:ASCII 與 Unicode?
    在Python中將字串轉換為二進位在Python中,您可能會遇到需要將字串表示為二進位數字序列的情況。這對於多種原因都很有用,例如資料加密或二進位檔案操作。 使用 bin() 函數將字串轉換為二進位的最簡單方法就是使用bin()函數。該函數接受一個字串作為輸入,並將其二進位表示形式傳回為字串。例如:...
    程式設計 發佈於2024-11-07
  • 為什麼從 Java 中的匿名內部類別存取外部實例變數需要是 Final?
    為什麼從 Java 中的匿名內部類別存取外部實例變數需要是 Final?
    Java內部類別:為什麼必須使用「最終」外部實例變數在Java中定義匿名內部類別時,您可能會遇到將外部實例變數標記為“final”的要求。本文探討了這個約束背後的原因。 如同提供的程式碼中所提到的,實例變數 jtfContent 必須宣告為 Final 才能在內部類別中存取。這項要求源自於 Java...
    程式設計 發佈於2024-11-07
  • 理解 Python 中的關鍵字參數
    理解 Python 中的關鍵字參數
    When you're programming in Python, knowing how to pass arguments to functions is key for writing clear, flexible, and easy-to-maintain code. One powe...
    程式設計 發佈於2024-11-07
  • 如何防止列印時DIV跨頁分割?
    如何防止列印時DIV跨頁分割?
    列印問題:防止 DIV 跨頁分叉遇到動態 DIV 在頁面之間切成兩半的列印困境?當嘗試列印具有大量可變高度 DIV 元素的冗長文件時,就會出現此問題。 CSS 救援解決方案為了解決此問題,CSS 屬性打破了 -裡面來拯救。透過指定值避免,您可以確保渲染引擎防止 DIV 中途分割。這是程式碼片段:@m...
    程式設計 發佈於2024-11-07
  • Python 是強類型語言嗎?
    Python 是強類型語言嗎?
    Python 是強型別語嗎? Python 中的強型別概念造成了一些混亂,因為該語言允許變數改變執行期間的類型。然而,Python 確實是強型別的,儘管是動態的。 Python 中的強型別強型別可確保值維持其宣告的型別,除非明確轉換。在Python中,這意味著變數沒有固定的類型,而是它們所保存的值有...
    程式設計 發佈於2024-11-07

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3