JavaScript 的 this 指向,一文解释清楚

开发
掌握 this 的指向,是理解 JavaScript 核心机制的关键,也是成为一名合格的 JavaScript 工程师的必备技能。本文将一次性讲清楚 JavaScript 的 this 指向,让你彻底摆脱 this 的困扰!

this,作为 JavaScript 中最令人困惑的概念之一,常常让开发者头疼不已。不同的调用方式、不同的上下文环境,都会导致 this 指向不同的对象。掌握 this 的指向,是理解 JavaScript 核心机制的关键,也是成为一名合格的 JavaScript 工程师的必备技能。本文将一次性讲清楚 JavaScript 的 this 指向,让你彻底摆脱 this 的困扰!

一、this 是什么?

简单来说,this 是一个关键字,它指向的是函数执行时的上下文对象。也就是说,this 的值取决于函数是如何被调用的,而不是函数在哪里定义的。

二、this 的四种绑定规则

JavaScript 中 this 的指向主要由以下四种绑定规则决定:

1. 默认绑定 (Default Binding)

示例:

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

foo(); // 非严格模式下,输出 window (浏览器) 或 global (Node.js)
       // 严格模式下,输出 undefined

"use strict";
function bar() {
  console.log(this);
}

bar(); // 输出 undefined
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 在非严格模式下,如果函数是独立调用(即没有明确的调用者),this 指向全局对象 (浏览器中是 window,Node.js 中是 global)。
  • 在严格模式下,this 指向 undefined。

2. 隐式绑定 (Implicit Binding)

示例:

如果函数作为对象的方法调用,this 指向调用该方法的对象。

3. 显式绑定 (Explicit Binding)

示例:

  • 可以使用 call()、apply() 或 bind() 方法来显式地指定 this 的指向。
  • call() 和 apply() 方法会立即执行函数,并将 this 绑定到指定的对象。它们的区别在于,call() 方法接收一个参数列表,而 apply() 方法接收一个参数数组。
  • bind() 方法会创建一个新的函数,并将 this 永久绑定到指定的对象。新函数不会立即执行,需要手动调用。

4. new 绑定 (new Binding)

示例:

当使用 new 关键字调用函数时,会发生以下步骤:

  • 创建一个新的空对象。
  • 将新对象的原型指向构造函数的 prototype 属性。
  • 将构造函数的 this 绑定到新对象。
  • 执行构造函数中的代码。
  • 如果构造函数没有显式返回一个对象,则返回新对象。

5. 优先级

当多个绑定规则同时适用时,this 的指向由优先级最高的规则决定。优先级从高到低依次为:

  • new 绑定
  • 显式绑定
  • 隐式绑定
  • 默认绑定

6. 特殊情况

(1) 箭头函数: 箭头函数没有自己的 this,它会从定义时所在的上下文中继承 this。箭头函数的 this 无法通过 call()、apply() 或 bind() 方法修改。

示例:

(2) DOM 事件处理函数: 在 DOM 事件处理函数中,this 通常指向触发事件的 DOM 元素。但可以使用 addEventListener() 方法的 bind() 方法来修改 this 的指向。

示例:

<button id="myButton">Click me</button>

<script>
  const button = document.getElementById("myButton");

  button.addEventListener("click", function() {
    console.log(this); // 输出: <button id="myButton">Click me</button>
  });

  const obj = {
    name: "MyObject"
  };

  button.addEventListener("click", function() {
    console.log(this.name);
  }.bind(obj)); // 输出: MyObject
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
责任编辑:赵宁宁 来源: JavaScript
相关推荐

2021-10-29 11:30:31

补码二进制反码

2022-04-07 08:37:05

链表技巧单链表

2022-08-15 15:39:23

JavaScript面向对象数据

2024-08-09 12:44:45

JavaScript原型链链条

2021-10-11 10:19:48

Javascript 高阶函数前端

2021-09-07 09:46:40

JavaScriptGenerator函数

2021-09-02 10:24:54

JavaScript前端语言

2024-11-19 13:20:55

2021-12-29 17:38:17

JavaScripttypeof前端

2018-05-21 07:08:18

行为驱动开发BDD编码

2023-02-28 18:09:53

Javascript定时器

2023-02-23 19:32:03

DOMJavascript开发

2023-01-26 01:09:31

配置数据源参数

2024-05-21 09:45:40

机器学习人工智能XAI

2019-12-17 08:16:04

JavaScriptthis编程

2021-09-09 10:26:26

Javascript 文档对象前端

2024-04-02 09:38:21

PythonGIL

2019-11-14 09:16:56

物联网技术路由器

2024-02-23 10:41:29

2019-08-06 09:00:00

JavaScript函数式编程前端
点赞
收藏

51CTO技术栈公众号