一文详解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)
相关推荐
创新技术阁1 小时前
FastapiAdmin 前后端启动全流程详解
前端·后端·fastapi
七牛开发者1 小时前
实测推荐 3 个 Skill,轻松上手 Codex 网页设计与交付流程
前端·javascript·后端
七牛开发者1 小时前
拆解 dsh 系列:从源码和版本变化看 DeepSeek Harness 的设计取舍
前端·javascript·后端
谭光志1 小时前
如何从网站提取设计风格:DOM、计算样式与 DESIGN.md
前端·javascript·agent
深念Y1 小时前
登录日志与管理员审计日志存储决策
前端·arm开发·后端·微服务·云原生·架构
笨笨饿2 小时前
#121_图传中的H.364编码与MP4的联系
linux·运维·前端·单片机·嵌入式硬件·面试·职场和发展
柒和远方2 小时前
V079: Milvus 向量数据库:AI 日记本的三组件部署、集合字段建模与余弦索引
javascript·sql
水獭比特2 小时前
Anthropic Files / Skills 迁移:Workspace 不是租户隔离,API Key 也不是用户身份
javascript
默_笙2 小时前
☕ 我给 TS 类型做了台"瘦身手术",还顺手用 Docker 起了个 MySQL
前端·javascript
leoZ2313 小时前
AI+前端提效- 06 AI辅助调试排错:前端报错、白屏、兼容问题极速定位
前端·人工智能·chatgpt·状态模式·超分辨率重建·openvino·dreamfusion