【最简单最全面】一文讲清楚五大this指向,this到底指向哪里?

举报
watermelo37 发表于 2025/06/30 22:09:19 2025/06/30
【摘要】         作者:watermelo37        CSDN万粉博主、华为云云享专家、阿里云专家博主、腾讯云、支付宝合作作者,全平台博客昵称watermelo37。        一个假装是giser的coder,做不只专注于业务逻辑的前端工程师,Java、Docker、Python、LLM均有涉猎。------------------------------------------...

        作者:watermelo37

        CSDN万粉博主、华为云云享专家、阿里云专家博主、腾讯云、支付宝合作作者,全平台博客昵称watermelo37。

        一个假装是giser的coder,做不只专注于业务逻辑的前端工程师,Java、Docker、Python、LLM均有涉猎。


---------------------------------------------------------------------

温柔地对待温柔的人,包容的三观就是最大的温柔。

---------------------------------------------------------------------

【最简单最全面】一文讲清楚五大this指向,this到底指向哪里?


一、this是什么?


        this 是 JavaScript 中最迷惑、最核心的概念之一。它的值不是取决于函数在哪声明的,而是取决于它是如何被调用的。

        简单来说,this 是函数运行时自动创建的一个特殊变量,它指向调用该函数的“拥有者”对象。但它的指向受不同的调用方式影响,我们一起来理一理五大this指向的情况。


二、五大情境下的this指向


1、默认绑定(函数独立调用)

        如果是函数直接使用this,那么this在浏览器环境下指向window,但在严格模式下 this === undefined,而不是 window。

function showThis() {
  console.log(this);
}
showThis(); // 浏览器环境下:this -> window

2、隐式绑定(对象调用)

        如果含有this的函数在对象里面,那么就看谁在点号前,this 就指谁。这里user调用了含有this的greet方法,所以this指向就是user。

const user = {
  name: 'Alice',
  greet() {
    console.log(this.name);
  }
};
user.greet(); // this -> user,输出 "Alice"

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

        关于apply和call不熟悉的可以看看这篇:改变函数调用上下文:apply与call方法详解及实例

        call/apply/bind这三个都是用来改变this指向的,其区别在于:call、apply会立即调用,指定 this,bind返回新函数,this 永远被绑定。

function greet() {
  console.log(this.name);
}
const person = { name: 'Bob' };

greet.call(person);  // this -> person,输出 "Bob"
greet.apply(person); // 同上
const bound = greet.bind(person);
bound();             // 同上

4、new 绑定(构造函数)

        用 new 创建对象时,this 指向这个新对象。

function Person(name) {
  this.name = name;
}
const p = new Person('Charlie'); // this -> 新创建的对象
console.log(p.name); // Charlie

5、箭头函数绑定

        这个应该是最难的一类了,很多人一直搞不清楚箭头函数的特殊性,也不理解特殊性是为了做什么。箭头函数没有自己的 this,它会继承外层作用域的 this,这样有助于其在回调或者事件里面能获得有用的this指向。

const person = {
  name: 'Eva',
  greet() {
    setTimeout(() => {
      console.log(this.name); // "Eva",因为箭头函数继承了外部 this
    }, 1000);
  }
};
person.greet();


三、判断this指向的3步心法(实战)


        按照如下三步依次判断即可:

  1. 有没有箭头函数? 👉 是的话,往上找作用域!

  2. 谁在调用这个函数? 👉 看点号前是谁

  3. 有没有 call/apply/bind 或 new? 👉 有就以指定对象为准


四、易出错的场景


1、this 被丢失

        虽然 fn = obj.say 是从对象上“取出”方法,但 你调用 fn() 时,它是作为一个“普通函数”调用的,没有上下文绑定。

        换句话说,它“脱离”了原本属于它的对象环境,默认绑定规则生效,this 就变成了 window(或 undefined,在严格模式下)。

        按照先前提出的隐式绑定“谁点它this就指向谁”,这里直接调用 fn() 效果等同 window.fn(),所以this指向就变成了window。

const obj = {
  name: 'Foo',
  say() {
    console.log(this.name);
  }
};
const fn = obj.say;
fn(); // this -> window (或 undefined)

        解决方案:用.bind(obj) 或箭头函数包装。

const fn = obj.say.bind(obj);
fn(); // this 始终是 obj

const fn = () => obj.say();
fn(); // this -> obj.say() 的 this 正常

2、在事件监听器中

        注意回调函数不同的写法this指向不同,直接写普通函数一般是为了修改DOM元素,比如this.style.backgroundColor = 'red'。写箭头函数一般是为了获取外层的数据、实例对象、上下文等,更常见。

const btn = document.querySelector('button');
btn.addEventListener('click', function () {
  console.log(this); // this -> 当前 DOM 元素(btn)
});

btn.addEventListener('click', () => {
  console.log(this); // this -> 外部作用域(可能是 window)
});


五、总结图解


调用方式 this 指向
普通函数

window(或 undefined,严格模式)

对象方法 调用该方法的对象
call/apply/bind 明确指定的对象
构造函数 新创建的对象
箭头函数 定义时所在作用域的 this


六、结语


        this 是动态的,取决于调用方式。箭头函数没有自己的 this,这是最常见的坑,掌握了这 5 条规则,配合调试/打印,基本能搞定 99% 场景。

        只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。