JavaScript this 指向详解

前言

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

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

比如:

  • 普通函数里的this

  • 对象方法里的this

  • 构造函数里的this

  • 箭头函数里的this

  • call、apply、bind改变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();

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

this是undefined。


三、对象方法中的 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就不会再那么抽象了。

相关推荐
兰亭妙微UI设计公司11 小时前
兰亭妙微ui设计公司分享:B端组件命名如何支持团队协作
前端·javascript·vue.js
小大宇12 小时前
Vue知识点-ElementPlus-03提示框+询问+通知
前端·javascript·vue.js
前端技术官12 小时前
前端的技术判断力是怎么练出来的?
javascript·web前端·localstorage·debounce·弱网处理
程序员大阳14 小时前
副队长JavaScript教程(60)-BOM 初识:window 对象与浏览器模型
javascript·bom·window对象·浏览器模型
web打印社区14 小时前
Chrome-kiosk-printing能上生产吗
开发语言·前端·javascript·chrome·websocket
志尊宝14 小时前
AI原生前端开发(041):AI辅助的状态管理(Zustand/Pinia)
前端·javascript·ai-native
Geoffwo14 小时前
DSH-SKILL基础
javascript
AI副业搞钱研究所14 小时前
用 12 组正则写一个骗局话术检测器:权重打分、硬红旗保底和高亮区间合并
javascript
程序员大阳14 小时前
副队长JavaScript教程(48)-异常处理基础
javascript·异常处理·finally·catch·try
志尊宝15 小时前
AI原生前端开发(038):AI辅助的Next.js 15全栈开发
javascript·人工智能·ai-native