首頁 > web前端 > js教程 > 為什麼「this」關鍵字在常規函數和箭頭函數中的行為不同

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

王林
發布: 2024-07-28 08:25:52
原創
667 人瀏覽過

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. 事件處理程序中的箭頭函數

事件處理程序中的箭頭函數從周圍的詞法範圍繼承此屬性,而不是從觸發事件的元素繼承。

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

  button.addEventListener('click', () => {
      console.log(this);
  }); // Logs the global object (window in browsers) or undefined in strict mode
登入後複製
  • Explanation: The arrow function does not bind this to the button element; it inherits it from the surrounding scope, which is the global scope or undefined in strict mode.

    • Strict Mode: Logs undefined, not the button element.

Why These Differences?

The difference between regular functions and arrow functions lies in how they handle this:

  • Regular Functions: The value of this is dynamic and determined by the call-site (how the function is called).
  • Arrow Functions: The value of this is lexical and set at the time the function is defined, based on the this value of the enclosing execution context.

Key Concepts to Understand

To understand the behavior of this in JavaScript, you need to know the following concepts:

  1. Execution Context: The context in which code is executed, affecting how this is determined.
  2. Call-site: The location in code where a function is called, influencing the value of this in regular functions.
  3. Lexical Scoping: How this is inherited in arrow functions from the surrounding scope.
  4. Strict Mode: How strict mode changes the default behavior of this in certain contexts.

Summary

  • Regular Functions: this is dynamic and determined by the call-site.
  • Arrow Functions: this is lexical and determined by the surrounding scope when the function is defined.

Understanding these distinctions will help you write more predictable and maintainable JavaScript code. Whether you're using regular functions or arrow functions, knowing how this works is crucial for effective JavaScript development.

以上是為什麼「this」關鍵字在常規函數和箭頭函數中的行為不同的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板