一文详解JavaScript中this:从绑定规则到箭头函数

对于许多JavaScript的初学者来说,this是一个让人又爱又恨的关键词,它的指向灵活多变,稍有不慎就会出现意想不到的结果。但是掌握this的绑定规则却是写出优雅,可复用的代码的必经之路。所以,本文将带你系统梳理this的来龙去脉,彻底搞懂它的工作机制。

一.为什么要有this

this 是 JS 中的一个关键字,它提供了一种更优雅的方式隐式的传递一个对象的引用,可以让代码更简洁易于复用。

js 复制代码
// 优雅的 this
const alice = {
  name: 'Alice',
  age: 25,
  introduce() {
    console.log(this.name);
  }
};
alice.introduce(); // this隐式传递了 alice 对象

二. this 可以出现在哪里?

1.全局

在浏览器中,全局中 this 指向 window 对象。

js 复制代码
console.log( this === window);// true

2.函数体内

函数内部的 this 指向取决于如何调用,而不是在哪里定义,这也是 this 最复杂也是最灵活的地方。

三.this 的绑定规则

1.默认绑定

当函数独立调用时,函数中的 this 指向 window 对象

js 复制代码
function foo(){
  console.log(this);
}

foo(); // window

2.隐式绑定

当一个函数被一个上下文对象所拥有,并被该对象调用,函数中的 this 指向该对象。

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

当一个函数被多层对象调用,函数中的 this 指向最近的那个对象

js 复制代码
function foo() {
  console.log(this.a);
}
var obj = {
  a: 1,
  foo: foo,
};

var oo = {
  a: 2,
  foo: obj,
};

oo.foo.foo(); // 1  离 foo 最近的对象是 obj 所以 this 指向 obj 对象

3.显示绑定

JavaScript中提供了三种方法 call, applybind,可以强制指定函数中的this

  • call :立即调用函数,参数逐个传递。
    fn.call(obj, x, y)

  • apply:立即调用函数,参数以数组方式传递。
    fn.apply(obj, [x, y]

  • bind:返回一个新的函数。
    fn.bind(obj, x, y)()

4.new 绑定

当一个函数被用作构造函数时, this 会指向新创建的那个实例对象。new的过程如下:

  1. 创建一个全新的空对象。

  2. 将这个空对象的 __proto__ 指向构造函数的 prototype

  3. 将构造函数内的 this 绑定到该新对象;

  4. 执行构造函数代码;

  5. 如果构造函数没有返回对象,则返回这个新对象。

js 复制代码
function Person(name) {
  this.name = name;
  this.say = function() {
    console.log(this.name);
  };
}
const alice = new Person('Alice');
alice.say(); // 'Alice',this 指向 alice 实例

四.箭头函数中的 this

箭头函数没有 this 这个概念,所以写在箭头函数中的 this ,是它外层非箭头函数的。

js 复制代码
function foo() {
  var fn = () => {
    this.a = 2;
  };
  fn();
}

var obj = {
  a: 1,
  bar: foo,
};
obj.bar(); // this 指向的是 obj 对象,所以相当于最后执行obj.a = 2,obj 对象中 a 的值变为 2
console.log(obj);  //obj { a: 2, bar: foo}

注意:如果箭头函数外面也没有普通函数,那么 this 指向全局

js 复制代码
const fn = () => {
  console.log(this); // window
};
fn();

五.一表总结

绑定类型 规则简述 示例场景
默认绑定 独立调用函数,this 指向全局 fn()
隐式绑定 通过对象调用,this 指向该对象(最近的那个) obj.fn()
显式绑定 使用 call/apply/bind 强制指定 this fn.call(obj)
new 绑定 作为构造函数调用,this 指向新实例 new Foo()
箭头函数 没有自己的 this,继承外层非箭头函数的 this () => console.log(this)
相关推荐
道里2 小时前
花了 5 万刀用 AI 写代码之后,这是我的全部经验
前端·人工智能
Royzst3 小时前
xml知识点
java·服务器·前端
IT_陈寒3 小时前
React useEffect闭包陷阱差点把我整失业了
前端·人工智能·后端
kyriewen4 小时前
推行AI写代码一年后,Code Review变成了新的加班理由
前端·ai编程·cursor
前端环境观察室4 小时前
给 Agent Browser Workflow 加一层可观测性:Trace、Snapshot 和 Review Queue
前端
柒瑞4 小时前
Superpowers结合Claude code浅实战
前端
Nian.Baikal5 小时前
从零搭建离线地图服务:Nginx + Cesium/Leaflet 实战指南
运维·前端·nginx
zithern_juejin5 小时前
new 运算符
javascript
前端毕业班5 小时前
uniapp web 灵活控制 style scoped
前端·javascript·vue.js
lichenyang4535 小时前
鸿蒙业务需求实战:AI 问题走马灯卡片实现复盘
前端