JavaScript this 指向详解

前言

在 JavaScript 中,this是一个非常高频、也非常容易让人混乱的知识点。

很多初学者会发现:同样是一个函数,在不同场景下调用this的值居然不一样。

比如:

  • 普通函数里的this

  • 对象方法里的this

  • 构造函数里的this

  • 箭头函数里的this

  • callapplybind改变this指向

本文就来系统讲清楚:JavaScript 中 this 到底指向谁。


一、this 是什么?

this不是在函数定义时决定的,而是在函数调用时决定的

也就是说:

谁调用这个函数,this 通常就指向谁。

先看一个简单例子:

javascript 复制代码
const obj = {
  name: 'Tom',
  say() {
    console.log(this.name);
  }
};

obj.say(); // Tom

这里say()是被obj调用的,所以this指向obj


二、普通函数中的 this

1)浏览器非严格模式下

scss 复制代码
function test() {
  console.log(this);
}

test();

在浏览器非严格模式下,普通函数直接调用时,

this指向window


2)严格模式下

javascript 复制代码
'use strict';

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

test();

严格模式下,普通函数直接调用时,

thisundefined


三、对象方法中的 this

如果函数作为对象的方法调用,那么this指向这个对象。

javascript 复制代码
const obj = {
  name: 'Alice',
  say() {
    console.log(this.name);
  }
};

obj.say(); // Alice

注意,真正决定this的,不是函数写在哪,而是怎么调用

ini 复制代码
const obj = {
  name: 'Alice',
  say() {
    console.log(this.name);
  }
};

const fn = obj.say;
fn(); // 浏览器非严格模式下通常是 undefined 或 window.name

这里fn()已经不是通过obj调用了,所以this不再指向obj


四、构造函数中的 this

当函数通过new调用时,this指向新创建的实例对象。

ini 复制代码
function Person(name) {
  this.name = name;
}

const p = new Person('Tom');
console.log(p.name); // Tom

这里this指向p


五、箭头函数中的 this

箭头函数没有自己的this,它的this取决于外层作用域

ini 复制代码
const obj = {
  name: 'Tom',
  say: () => {
    console.log(this.name);
  }
};

obj.say();

这里箭头函数不会绑定obj,而是继承外层的this

如果在浏览器全局环境下,通常指向window


一个更容易理解的例子

ini 复制代码
const obj = {
  name: 'Tom',
  say() {
    const fn = () => {
      console.log(this.name);
    };
    fn();
  }
};

obj.say(); // Tom

这里箭头函数fn继承了say()this,也就是obj


六、事件中的 this

在 DOM 事件中,普通函数里的this一般指向触发事件的元素。

javascript 复制代码
button.onclick = function () {
  console.log(this); // button 元素
};

如果写成箭头函数:

ini 复制代码
button.onclick = () => {
  console.log(this);
};

那么这里的this不再指向按钮,而是继承外层作用域。


七、call、apply、bind 改变 this

JavaScript 提供了三种显式改变this的方法:

  • call
  • apply
  • bind
arduino 复制代码
function say() {
  console.log(this.name);
}

const obj = { name: 'Tom' };

say.call(obj);  // Tom
say.apply(obj); // Tom

bind 不会立即执行,而是返回一个新的函数:

ini 复制代码
const fn = say.bind(obj);
fn(); // Tom

八、this 指向总结

可以简单记住下面几条:

  1. 普通函数直接调用 :浏览器非严格模式下指向 window

  2. 对象方法调用:指向调用它的对象

  3. 构造函数调用:指向新实例

  4. 箭头函数 :没有自己的 this ,继承外层

  5. call/apply/bind :可以显式指定 this


九、总结

this的核心不是"函数定义在哪",而是:

函数是如何被调用的。

只要抓住这句话,再结合几种常见场景,this就不会再那么抽象了。

相关推荐
ct97821 小时前
组件间的通信
前端·javascript·vue.js
左手吻左脸。21 小时前
Vue 全栈面试题大全(2026 最新版最详细)
前端·javascript·vue.js
两个西柚呀1 天前
js中的同步和异步,三种处理异步任务的方式
前端·javascript
小新1101 天前
最简单但完整的 Vue 响应式示例(一个简单的计数器按钮)
前端·javascript·vue.js
川冰ICE1 天前
JavaScript进阶④|Symbol与元编程,对象的隐藏身份
开发语言·javascript·ecmascript
水煮白菜王1 天前
开源 AI 桌宠 Clawd on Desk:让 Claude Code 的状态从终端‘蹦‘到桌面
javascript·人工智能·开源
吃口巧乐兹1 天前
异步异常处理:AggregateException 的拆解与最佳实践
javascript
柒和远方1 天前
每日一学V017:用 Prompt 做 NLP:解构赋值与 AI 全栈的第一次实战
javascript·架构·代码规范
砍材农夫1 天前
物联网实战:Spring Boot MQTT | 模拟器Paho客户端拆解高性能
java·javascript·spring boot·后端·物联网·struts
代码小库1 天前
【2026前端最新面试题——day10】JavaScript 高频面试题
开发语言·前端·javascript