JS-2026年了,你真的懂 JavaScript 的 this 指向吗?

42 阅读2分钟

前言

在 JavaScript 中,this 的指向不是在编写时确定的,而是在执行时确定的。理解 this 的关键在于:谁调用了它,它就指向谁(除了箭头函数)

一、 this 的四大绑定规则

1. 默认绑定(全局环境)

在全局作用域或普通函数调用中,this 指向全局对象。

  • 浏览器环境:指向 window
  • 严格模式 ('use strict') :指向 undefined

2. 隐式绑定(对象方法)

当函数作为对象的方法被调用时,this 指向该对象。

const obj = {
  a: 1,
  func() { console.log(this.a); }
};
obj.func(); // 1(this 指向 obj)

⚠️ 隐式丢失:将方法赋值给变量后再调用,this 会指向全局。

const func1 = obj.func;
func1(); // undefined(此时为独立调用,this 指向 window)

3. 显式绑定(call/apply/bind)

通过 callapplybind 强行改变 this 的指向。

4. new 绑定(构造函数)

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


二、 箭头函数:异类的 this

箭头函数没有自己的 this 它的 this 继承自外层(父级)执行上下文

  • 定义时绑定:它在定义时就已经确定了指向,且后续无法通过 call/bind 改变。
  • 不指向调用者:它不看谁调用,只看它诞生在哪里。

JavaScript

function func(){
  const func2 = () => {
    console.log(this); // 这里的 this 继承自 func 的执行上下文
  }
  func2();
}
func(); // window

三、 原型链与 HTML 事件中的 this

1. 原型链方法

在原型链上添加方法时,this 指向当前调用该方法的实例对象

Function.prototype.myBind = function(thisArg) {
  console.log(this); // 这里的 this 指向调用 myBind 的那个函数对象
};

2. HTML 事件处理

在 HTML 元素的事件属性中,this 指向当前的 HTML 元素本身

<div onclick="console.log(this)">点击我</div> 
//this指向Html元素

四、 面试模拟题(挑战一下)

Q1:嵌套函数中的 this 是如何表现的?如何解决指向丢失?

参考回答: 嵌套函数(非箭头函数)独立调用时,this 指向全局。解决办法有:

  1. 使用箭头函数(最推荐)。
  2. 在外层函数定义 let self = this;,在内层通过 self 访问。
  3. 使用 bind 强行锁定。

Q2:箭头函数可以作为构造函数吗?为什么?

参考回答: 不可以。因为:

  1. 箭头函数没有自己的 this,无法指向新创建的实例。
  2. 箭头函数没有 prototype 属性。
  3. 箭头函数没有 arguments 对象。

Q3:说出以下代码的执行结果:

var name = "window";
const person = {
  name: "obj",
  sayName: () => {
    console.log(this.name);
  }
};
person.sayName();

参考回答: 结果是 "window"

解析person 是一个对象字面量,它没有自己的块级作用域。箭头函数 sayName 在定义时,其父级上下文是全局执行上下文(window),因此 this 指向 window