likes
comments
collection
share

你真的懂this吗?一、什么是 this? 在 JavaScript 中,this 是一个引用当前执行上下文的对象。执行

作者站长头像
站长
· 阅读数 26

this 关键字是 JavaScript 中最重要和最容易混淆的概念之一。它的值不仅取决于代码的执行上下文,还可以通过不同的调用方式动态改变。本文将详细探讨 JavaScript 中 this 的工作原理、不同情况下 this 的取值,以及如何正确使用 this 关键字。

一、什么是 this?

在 JavaScript 中,this 是一个引用当前执行上下文的对象。执行上下文指的是代码运行时的环境,this 的值会根据执行上下文的不同而变化。this 关键字允许函数在不同的上下文中访问和操作对象。

二、this 的工作原理

JavaScript 中 this 的值取决于函数的调用方式。以下是常见的调用方式及其对应的 this 绑定规则:

  • 全局上下文中的 this
  • 对象方法中的 this
  • 构造函数中的 this
  • 箭头函数中的 this
  • 显式绑定的 this

1. 全局上下文中的 this

在全局执行上下文中(即在函数之外),this 引用的是全局对象。在浏览器中,全局对象是 window,在 Node.js 中则是 global

示例:

console.log(this); // 浏览器中输出 window 对象,Node.js 中输出 global 对象

在非严格模式下,未绑定到任何对象的函数中的 this 默认指向全局对象。

示例:

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

showThis(); // 浏览器中输出 window 对象,Node.js 中输出 global 对象

在严格模式 (use strict) 下,this 不再指向全局对象,而是 undefined

示例:

"use strict";

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

showThis(); // 输出 undefined

2. 对象方法中的 this

this 在对象的方法中使用时,它指向调用该方法的对象。

示例:

const obj = {
  name: "Alice",
  showThis: function () {
    console.log(this);
  },
};

obj.showThis(); // 输出 obj 对象

在这个例子中,showThis 方法中的 this引用 obj 对象,这是因为 showThis 是由 obj 调用的。

如果将方法赋值给一个变量,再调用该变量,this 的指向会改变。

示例:

const obj = {
  name: "Alice",
  showThis: function () {
    console.log(this);
  },
};

const anotherFunc = obj.showThis;
anotherFunc(); // 浏览器中输出 window 对象,Node.js 中输出 global 对象

由于 anotherFunc 是在全局上下文中调用的,this 指向了全局对象。

3. 构造函数中的 this

当使用 new 关键字调用函数时,this 指向新创建的对象。

示例:

function Person(name) {
  this.name = name;
}

const person = new Person("Alice");
console.log(person.name); // 输出 "Alice"

在这个例子中,this 在构造函数 Person 中引用新创建的对象,因此 this.name = namename 属性绑定到新对象上。

箭头函数中的 this

箭头函数与传统函数的一个重要区别在于它们不绑定自己的 this 值。箭头函数中的 this 始终指向它被定义时所在的词法作用域中的 this 值。

示例:

const obj = {
  name: "Alice",
  showThis: function () {
    const arrowFunc = () => {
      console.log(this);
    };
    arrowFunc();
  },
};

obj.showThis(); // 输出 obj 对象

在这个例子中,箭头函数 arrowFuncthis 继承自 showThis 方法的 this,因此它指向 obj

即使箭头函数被赋值给另一个变量,其 this 绑定也不会改变。

示例:

const obj = {
  name: "Alice",
  showThis: function () {
    const arrowFunc = () => {
      console.log(this);
    };
    return arrowFunc;
  },
};

const anotherFunc = obj.showThis();
anotherFunc(); // 输出 obj 对象

5. 显式绑定的 this

JavaScript 提供了三种方法来显式绑定 this 值:callapplybind

  • callapply: 这两个方法用于立即调用函数,并在调用时显式设置 this 的值。它们的区别在于传递参数的方式,call 接受多个参数,而 apply 接受一个参数数组。

示例:

function showName() {
  console.log(this.name);
}

const person1 = { name: "Alice" };
const person2 = { name: "Bob" };

showName.call(person1); // 输出 "Alice"
showName.apply(person2); // 输出 "Bob"
  • bindbind 方法用于创建一个新函数,并永久绑定 this 的值。新函数可以稍后调用。

    示例:

function showName() {
  console.log(this.name);
}

const person = { name: "Alice" };
const boundFunc = showName.bind(person);

boundFunc(); // 输出 "Alice"

在这个例子中,bind 返回一个新函数,该函数的 this 永远绑定到 person 对象。

三、this 关键字的实际应用

理解和正确使用 this 是编写复杂 JavaScript 应用程序的关键。以下是一些实际应用场景:

1. 在对象方法中访问对象属性

this 使得方法能够访问和操作调用它的对象的属性。

示例:

const counter = {
  value: 0,
  increment: function () {
    this.value++;
    console.log(this.value);
  },
};

counter.increment(); // 输出 1
counter.increment(); // 输出 2

2. 在事件处理程序中引用元素

在 DOM 事件处理程序中,this 通常引用触发事件的元素。

示例:

document.getElementById("myButton").addEventListener("click", function () {
  console.log(this.id); // 输出 "myButton"
});

在这个例子中,this 引用触发点击事件的按钮元素。

3. 使用 bind 创建回调函数

bind 方法常用于将 this 绑定到特定对象,特别是在回调函数中。

示例:

function Timer() {
  this.seconds = 0;
  setInterval(
    function () {
      this.seconds++;
      console.log(this.seconds);
    }.bind(this),
    1000
  );
}

const timer = new Timer();
// 每秒输出 1, 2, 3, ...

在这个例子中,bind 方法确保 setInterval 的回调函数中的 this 指向 Timer 实例。

四、总结

this 关键字在 JavaScript 中是一个强大且灵活的工具,但同时也是一个容易混淆的概念。它的值取决于函数的调用方式,而不是函数定义的位置。在编写 JavaScript 代码时,理解 this 的工作原理和不同的绑定规则非常重要,这样可以避免常见的错误,如 this 指向意外的对象。

P.S.

本文首发于我的个人网站www.aifeir.com,若你觉得有所帮助,可以点个爱心鼓励一下,如果大家喜欢这篇文章,希望多多转发分享,感谢大家的阅读。

转载自:https://juejin.cn/post/7406899773796483083
评论
请登录