首页 >web前端 >js教程 >为什么'this”关键字在常规函数和箭头函数中的行为不同

为什么'this”关键字在常规函数和箭头函数中的行为不同

王林
王林原创
2024-07-28 08:25:52650浏览

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn