ホームページ >ウェブフロントエンド >jsチュートリアル >「this」キーワードが通常の関数とアロー関数で異なる動作をする理由

「this」キーワードが通常の関数とアロー関数で異なる動作をする理由

王林
王林オリジナル
2024-07-28 08:25:52649ブラウズ

Why the

JavaScript の this キーワードは、通常の関数とアロー関数で動作が異なるため、混乱を招く可能性があります。このブログ投稿では、これが両方のタイプの関数でどのように機能するかを説明し、これらの違いが存在する理由を探り、JavaScript でこれを理解するために必要な基本的な知識を提供します。

通常の関数

JavaScript の通常の関数は、function キーワードを使用して定義されます。これらの関数の this の値は、関数の呼び出し方法によって異なります。以下にいくつかの例を示します:

1. グローバルコンテキスト

  • 非厳密モード:
  function regularFunction() {
      console.log(this);
  }

  regularFunction(); // Logs the global object (window in browsers)
  • 説明: 非厳密モードでは、関数がグローバル コンテキスト (オブジェクトのメソッドとしてではなく) で呼び出される場合、これはグローバル オブジェクト (ブラウザーのウィンドウまたはノードのグローバル) を参照します。 .js).

    • 厳密モード:
  'use strict';

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

  regularFunction(); // Logs undefined
  • 説明: 厳密モードでは、関数がグローバル コンテキストで呼び出されるとき、これは未定義のままであり、グローバル オブジェクトへの偶発的な変更を防ぐことでより安全な環境を提供します。

2. メソッド呼び出し

関数がオブジェクトのメソッドとして呼び出される場合、これはそのオブジェクトを参照します。

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

  obj.method(); // Logs obj
  • 説明: この場合、関数は obj のメソッドとして呼び出されるため、これは obj を指します。

    • 厳密モード: 動作は厳密モードでも同じです。

3. コンストラクター呼び出し

関数がコンストラクターとして使用される場合 (new キーワードで呼び出される)、これは新しく作成されたインスタンスを参照します。

  • 例:
  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. 明示的なバインディング

呼び出し、適用、またはバインドを使用してこれを明示的にバインドできます。

  • 例:
  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 and apply は、この関数を obj に設定して即座に呼び出しますが、bind はこれを obj に永続的にバインドした新しい関数を作成します。

    • 厳密モード: 動作は厳密モードでも同じです。

アロー関数

ES6 で導入されたアロー関数には、独自の this コンテキストがありません。代わりに、周囲の (語彙) スコープからこれを継承します。これにより、特定の状況で矢印関数が便利になります。

1. 語彙的これ

アロー関数は、定義されているスコープからこれを継承します。

  • 非厳密モード:
  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 をバインドせず、字句スコープから継承します。この例では、これは、obj.

    ではなく、グローバル オブジェクト、または厳密モードの未定義を参照します。
    • 厳密モード: obj ではなく、未定義のログを記録します。

3. 別の関数内のアロー関数

アロー関数が別の関数内で定義されている場合、その関数は外側の関数からこれを継承します。

  • 例:
  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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。