JavaScript中this的5大核心规则详解

在 JavaScript 中,this 是一个特殊关键字,其值取决于函数的 调用方式 而非定义位置。它的行为遵循一套明确的规则,以下是核心规则和示例:


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

当函数独立调用时(不作为方法、构造函数等),this 指向全局对象:

  • 浏览器中window
  • Node.js 中global
function show() {
  console.log(this); // 浏览器:Window / Node.js:global
}
show(); // 独立调用

严格模式('use strict')下thisundefined


2. 隐式绑定(方法调用)

当函数作为对象方法调用时,this 指向 调用该方法的对象

const user = {
  name: "Alice",
  greet() {
    console.log(`Hello, ${this.name}!`);
  }
};
user.greet(); // "Hello, Alice!"(this = user)

⚠️ 易错点:绑定丢失
若将方法赋值给变量后调用,会丢失原始绑定,退回到默认绑定:

const greet = user.greet;
greet(); // "Hello, undefined!"(this 指向全局)

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

通过 call()apply()bind() 强制指定 this

function greet() {
  console.log(`Hello, ${this.name}!`);
}

const alice = { name: "Alice" };
const bob = { name: "Bob" };

// call/apply 立即调用
greet.call(alice); // "Hello, Alice!"(this = alice)
greet.apply(bob);  // "Hello, Bob!"(this = bob)

// bind 创建新函数(永久绑定)
const boundGreet = greet.bind(alice);
boundGreet(); // "Hello, Alice!"

4. new 绑定(构造函数)

使用 new 调用构造函数时,this 指向 新创建的对象

function Person(name) {
  this.name = name; // this = 新对象
}
const alice = new Person("Alice");
console.log(alice.name); // "Alice"

5. 箭头函数:词法作用域绑定

箭头函数 没有自己的 this,它会继承外层作用域的 this(定义时绑定,非调用时):

const user = {
  name: "Alice",
  greet: function() {
    // 普通函数:this = user
    setTimeout(() => {
      console.log(`Hello, ${this.name}!`); // this 继承自 greet
    }, 100);
  }
};
user.greet(); // "Hello, Alice!"(箭头函数捕获了 user)

⚠️ 注意

  • 箭头函数的 this 不可通过 call/bind 修改。
  • 对象字面量、类中的箭头函数会绑定到外层作用域(可能是全局)。

特殊场景总结

场景this 指向示例
独立函数调用全局对象(严格模式为 undefinedfunc()
对象方法调用调用该方法的对象obj.method()
call/apply/bind显式指定的对象func.call(ctx)
new 构造函数新创建的对象实例new Constructor()
箭头函数外层词法作用域的 this() => { ... }
DOM 事件处理触发事件的元素button.onclick = func

常见问题解决技巧

  1. 方法绑定丢失:用 bind() 或箭头函数固定 this

    // 方法1: bind
    const boundMethod = obj.method.bind(obj);
    // 方法2: 箭头函数
    obj.method = () => { ... };
    
  2. 回调函数中的 this

    • 使用箭头函数保留外层 this
    • 显式绑定:setTimeout(function() {...}.bind(this), 100)
  3. 类中的方法:使用箭头函数或手动绑定,避免丢失 this

    class Counter {
      count = 0;
      // 方案1: 类字段(箭头函数)
      increment = () => {
        this.count++;
      };
      // 方案2: 构造函数中绑定
      constructor() {
        this.decrement = this.decrement.bind(this);
      }
      decrement() {
        this.count--;
      }
    }
    

终极秘诀

this 的值在函数调用时确定,而非定义时。
始终问自己:这个函数是如何被调用的?

  • obj.func()this = obj
  • func()this = 全局/undefined
  • new Func()this = 新对象
  • 箭头函数 → 继承外层 this
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码的余温

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值