」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 為什麼「this」關鍵字在常規函數和箭頭函數中的行為不同

為什麼「this」關鍵字在常規函數和箭頭函數中的行為不同

發佈於2024-07-30
瀏覽:804

Why the \

JavaScript 中的 this 关键字可能会令人困惑,因为它在常规函数和箭头函数中的行为不同。在这篇博文中,我们将解释这在两种类型的函数中如何工作,探讨为什么存在这些差异,并提供在 JavaScript 中理解这一点所需的基本知识。

常规功能

JavaScript 中的常规函数​​是使用 function 关键字定义的。这些函数中 this 的值取决于函数的调用方式。以下是几个例子:

1. 全球背景

  • 非严格模式:
  function regularFunction() {
      console.log(this);
  }

  regularFunction(); // Logs the global object (window in browsers)
  • 说明: 在非严格模式下,当在全局上下文中调用函数时(不是作为对象的方法),this 指的是全局对象(浏览器中的 window 或 Node 中的 global) .js).

    • 严格模式:
  'use strict';

  function regularFunction() {
      console.log(this);
  }

  regularFunction(); // Logs undefined
  • 说明:在严格模式下,当在全局上下文中调用函数时,this 保持未定义状态,通过防止意外修改全局对象来提供更安全的环境。

2. 方法调用

当函数作为对象的方法被调用时,this 引用该对象。

  • 例子:
  const obj = {
      method: function() {
          console.log(this);
      }
  };

  obj.method(); // Logs obj
  • 解释: 在本例中,this 指向 obj,因为该函数作为 obj 的方法被调用。

    • 严格模式:严格模式下的行为保持不变。

3. 构造函数调用

当函数用作构造函数(使用 new 关键字调用)时,this 指的是新创建的实例。

  • 例子:
  function Person(name) {
      this.name = name;
      this.sayHello = function() {
          console.log(`Hello, my name is ${this.name}`);
      };
  }

  const person1 = new Person('Alice');
  person1.sayHello(); // Logs "Hello, my name is Alice"

  const person2 = new Person('Bob');
  person2.sayHello(); // Logs "Hello, my name is Bob"
  • 说明: 当使用 new 调用时,Person 构造函数中的 this 指的是正在创建的新实例。每个新实例(person1 和 person2)都有自己的 name 属性和 sayHello 方法。

    • 严格模式:严格模式下的行为保持不变。

4. 显式绑定

您可以使用call、apply或bind显式绑定它。

  • 例子:
  function regularFunction() {
      console.log(this);
  }

  const obj = { value: 42 };

  regularFunction.call(obj);  // Logs obj
  regularFunction.apply(obj); // Logs obj

  const boundFunction = regularFunction.bind(obj);
  boundFunction();            // Logs obj
  • 说明: call 和 apply 立即调用将 this 设置为 obj 的函数,而 bind 创建一个新函数,并将 this 永久绑定到 obj。

    • 严格模式:严格模式下的行为保持不变。

箭头功能

ES6 中引入的箭头函数没有自己的 this 上下文。相反,它们从周围的(词法)范围继承这一点。这使得箭头函数在某些情况下很有用。

1. 词法 this

箭头函数从定义它们的作用域继承它。

  • 非严格模式:
  const arrowFunction = () => {
      console.log(this);
  };

  arrowFunction(); // Logs the global object (window in browsers)
  • 说明:箭头函数没有自己的this;他们从周围的范围内使用这个。这里,它指的是全局对象,因为该函数是在全局范围内定义的。

    • 严格模式:
  'use strict';

  const arrowFunction = () => {
      console.log(this);
  };

  arrowFunction(); // Logs undefined
  • 解释: 在严格模式下,如果周围作用域是全局的,则它保持未定义状态,因为从周围作用域继承。

2. 方法调用

与常规函数不同,箭头函数在作为方法调用时不会获得自己的 this。他们从封闭范围继承了这一点。

  • 例子:
  const obj = {
      method: () => {
          console.log(this);
      }
  };

  obj.method(); // Logs the global object (window in browsers) or undefined in strict mode
  • 说明:箭头函数不绑定自己的this,而是从词法作用域继承它。在这个例子中,this指的是全局对象或严格模式下的undefined,而不是obj.

    • 严格模式: 日志未定义,而不是 obj。

3.另一个函数内的箭头函数

当箭头函数在另一个函数内部定义时,它会从外部函数继承 this。

  • 例子:
  function outerFunction() {
      const arrowFunction = () => {
          console.log(this);
      };

      arrowFunction();
  }

  const obj = { value: 42, outerFunction: outerFunction };

  obj.outerFunction(); // Logs obj, because `this` in arrowFunction is inherited from outerFunction
  • 说明:此时,箭头函数内部的this指的是与outerFunction中相同的this,即obj.

    • 严格模式:严格模式下的行为保持不变。

4. 事件处理程序中的箭头函数

事件处理程序中的箭头函数从周围的词法范围继承此属性,而不是从触发事件的元素继承。

  • 例子:
  const button = document.querySelector('button');

  button.addEventListener('click', () => {
      console.log(this);
  }); // Logs the global object (window in browsers) or undefined in strict mode
  • 说明:箭头功能不将this绑定到按钮元素;它从周围的作用域继承它,该作用域是全局作用域或在严格模式下未定义。

    • 严格模式: 记录未定义的日志,而不是按钮元素。

为什么会有这些差异?

常规函数和箭头函数的区别在于它们的处理方式:

  • 常规函数: this 的值是动态的,由调用点(函数如何调用)决定。
  • 箭头函数: this 的值是词法的,并在定义函数时根据封闭执行上下文的 this 值进行设置。

需要理解的关键概念

要理解 JavaScript 中 this 的行为,您需要了解以下概念:

  1. 执行上下文: 代码执行的上下文,影响其确定方式。
  2. Call-site: 代码中调用函数的位置,影响常规函数中 this 的值。
  3. 词法作用域: this 如何在箭头函数中从周围作用域继承。
  4. 严格模式: 严格模式如何在某些上下文中改变 this 的默认行为。

概括

  • 常规函数:这是动态的,由调用站点决定。
  • 箭头函数: 这是词法的,由定义函数时的周围范围决定。

理解这些区别将帮助您编写更可预测和可维护的 JavaScript 代码。无论您使用常规函数还是箭头函数,了解其工作原理对于有效的 JavaScript 开发都至关重要。

版本聲明 本文轉載於:https://dev.to/hargun_singh/why-the-this-keyword-behaves-differently-in-regular-functions-and-arrow-functions-52j6?1如有侵犯,請聯絡study_golang@163 .com刪除
最新教學 更多>
  • Hexabot 設定與視覺化編輯教學:建立您的第一個 AI 聊天機器人
    Hexabot 設定與視覺化編輯教學:建立您的第一個 AI 聊天機器人
    聊天機器人愛好者大家好!在本教程中,我們將引導您完成設定和使用開源 AI 聊天機器人建構器 Hexabot 的過程。我們將首先克隆 GitHub 儲存庫、安裝依賴項並為 Hexabot 配置環境變數。您還將學習如何使用 Docker 啟動專案、存取管理面板以及使用視覺化編輯器建立聊天機器人流程。 ...
    程式設計 發佈於2024-11-02
  • mysql_fetch_row()、mysql_fetch_assoc() 和 mysql_fetch_array():您應該選擇哪一個?
    mysql_fetch_row()、mysql_fetch_assoc() 和 mysql_fetch_array():您應該選擇哪一個?
    mysql_fetch_row()、mysql_fetch_assoc() 和mysql_fetch_array() 解釋背景:[&SQL&]如果您正在使用已棄用的MyMy擴充功能中,在從結果集中檢索資料的mysql_fetch_row()、mysql_fetch_assoc() 和mysql_fe...
    程式設計 發佈於2024-11-02
  • Next.js - 概述
    Next.js - 概述
    本文作為初學者友好的指南和使用 Next.js 的步驟。 Next.js 是一個用於建立 Web 應用程式的靈活框架。相反,它是一個建立在 Node.js 之上的 React 框架。 設定您的 Next.js 專案 要啟動新的 Next.js 項目,您需要在電腦上安裝 Node.js。 安裝 ...
    程式設計 發佈於2024-11-02
  • 如何在程式碼中使用 Unsplash 圖片
    如何在程式碼中使用 Unsplash 圖片
    身為從事新 SaaS 專案的開發人員,我需要直接透過 URL 連結一些 Unsplash 圖片。 最初,我看到一篇推薦使用 https://source.unsplash.com/ API 的文章(連結)。但是,此方法不再有效,僅從 URL 欄位複製連結並不能提供嵌入所需的直接圖像 URL。 h...
    程式設計 發佈於2024-11-02
  • 如何合併關聯數組、處理缺失鍵、填滿預設值?
    如何合併關聯數組、處理缺失鍵、填滿預設值?
    合併多個關聯數組並添加具有預設值的缺失列將關聯數組與不同的鍵集組合起來創建統一的數組可能具有挑戰性。這個問題探索了一種實現此目的的方法,所需的輸出是一個數組,其中鍵被合併,缺失的列用預設值填充。 為了實現這一點,建議結合使用 array_merge 函數精心設計的鍵數組:$keys = array(...
    程式設計 發佈於2024-11-02
  • 透過 testcontainers-go 和 docker-compose 來利用您的測試套件
    透過 testcontainers-go 和 docker-compose 來利用您的測試套件
    Welcome back, folks! Today, we will cover the end-to-end tests in an intriguing blog post. If you've never written these kinds of tests or if you stri...
    程式設計 發佈於2024-11-02
  • 以下是一些適合您文章的基於問題的標題:

**直接簡潔:**

* **如何在Windows控制台中正確顯示UTF-8字元? ** **
* **為什麼傳統方法無法顯示
    以下是一些適合您文章的基於問題的標題: **直接簡潔:** * **如何在Windows控制台中正確顯示UTF-8字元? ** ** * **為什麼傳統方法無法顯示
    在Windows 控制台中正確顯示UTF-8 字元使用傳統方法在Windows 控制台中顯示UTF-8 字元的許多嘗試均失敗正確渲染擴充字元。 失敗嘗試:一個使用 MultiByteToWideChar() 和 wprintf() 的常見方法被證明是無效的,只留下 ASCII 字元可見。此外,使用 ...
    程式設計 發佈於2024-11-02
  • ReactJS 的模擬介紹
    ReactJS 的模擬介紹
    ReactJS 19:重要部份 並發模式增強: ReactJS 19 中最大的改進是並發模式,它不僅在應用程式自身更新時保持UI 平滑和響應靈敏,而且還確保了無縫界面,尤其是在復雜的過渡(例如動畫)時。 改進的伺服器元件: 在 Python 的引領下,ReactJ...
    程式設計 發佈於2024-11-02
  • 首屆DEV網頁遊戲挑戰賽評審
    首屆DEV網頁遊戲挑戰賽評審
    我被要求對DEV團隊9月份組織的第一屆網頁遊戲挑戰賽提交的參賽作品進行評判,結果在10月初發布。 我們幾個月來一直在 DEV 上組織挑戰(迷你黑客馬拉松),併計劃宣布我們的第一個網頁遊戲挑戰。鑑於您在遊戲社群 和 dev.to 的專業知識和參與度,我們想知道您是否有興趣成為客座評審。 誰能對此說...
    程式設計 發佈於2024-11-02
  • 購買經過驗證的現金應用程式帳戶:安全可靠的交易
    購買經過驗證的現金應用程式帳戶:安全可靠的交易
    Buying verified Cash App accounts is not recommended. It can lead to security risks and potential account bans. If you want to more information just k...
    程式設計 發佈於2024-11-02
  • 為什麼 `std::function` 缺乏相等比較?
    為什麼 `std::function` 缺乏相等比較?
    揭開std::function 的等式可比性之謎難題:為什麼是std::&&]難題:為什麼是std:: function,現代C 程式碼庫的一個組成部分,不具備相等比較功能?這個問題從一開始就困擾著程式設計師,導致管理可呼叫物件集合的混亂和困難。 早期的歧義:在C 語言的早期草案中11 標準中,op...
    程式設計 發佈於2024-11-02
  • JavaScript 類型檢查 |程式設計教學
    JavaScript 類型檢查 |程式設計教學
    介紹 本文涵蓋以下技術技能: 在本實驗中,我們將探索一個 JavaScript 函數,該函數檢查提供的值是否屬於指定類型。我們將使用 is() 函數,它利用建構子屬性和 Array.prototype.includes() 方法來確定值是否屬於指定類型。本實驗將幫助您更了解 Jav...
    程式設計 發佈於2024-11-02
  • 使用 Streamlit 將機器學習模型部署為 Web 應用程式
    使用 Streamlit 將機器學習模型部署為 Web 應用程式
    介绍 机器学习模型本质上是一组用于进行预测或查找数据模式的规则或机制。简单地说(不用担心过于简单化),在 Excel 中使用最小二乘法计算的趋势线也是一个模型。然而,实际应用中使用的模型并不那么简单——它们通常涉及更复杂的方程和算法,而不仅仅是简单的方程。 在这篇文章中,我将首先构...
    程式設計 發佈於2024-11-02
  • ## utf8_unicode_ci 與 utf8_bin:哪一種 MySQL 排序規則最適合德國網站?
    ## utf8_unicode_ci 與 utf8_bin:哪一種 MySQL 排序規則最適合德國網站?
    為德語選擇最佳MySQL 排序規則為德語選擇最佳MySQL 排序規則在設計為德語受眾量身定制的網站時,支持像ä、 ü 和ß。當涉及特定於語言的要求時,排序規則的選擇起著重要作用。 字元集和排序規則對於字元處理,UTF-8 仍然是首選選項,提供廣泛的字元支援。至於排序規則,則需要考慮德語特定字元。 排...
    程式設計 發佈於2024-11-02
  • 異常處理基礎知識
    異常處理基礎知識
    Java中的例外處理由五個關鍵字管理:try、catch、 throw、throws和finally。 這些關鍵字構成了一個相互關聯的子系統。 要監視的指令位於 try 區塊內。 如果try區塊中發生異常,則會拋出異常。 程式碼可以使用catch捕獲並處理異常。 系統異常由Java執行時...
    程式設計 發佈於2024-11-02

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

Copyright© 2022 湘ICP备2022001581号-3