核心方法是切断函数与调用位置的隐式关联,再通过call、apply、bind显式指定this值;箭头函数继承外层普通函数的this;手动绑定可防止赋值或传参时this丢失;call还可模拟构造函数调用。

要绕过 this 的默认绑定规则,核心方法是**切断函数与调用位置的隐式关联**,再通过显式手段指定执行时的 this 值。
使用 call、apply 或 bind
这三个方法都能强制指定函数运行时的 this,区别在于调用时机和参数传入方式:
-
func.call(obj, arg1, arg2):立即执行,参数逐个传入 -
func.apply(obj, [arg1, arg2]):立即执行,参数以数组形式传入 -
const boundFunc = func.bind(obj, arg1):返回一个新函数,this永久绑定为obj,可后续调用
箭头函数(无自己的 this)
箭头函数不遵循默认绑定、隐式绑定或显式绑定规则,它会**继承外层普通函数作用域的 this 值**。适合在回调、定时器等容易丢失 this 的场景中“固化”上下文:
const obj = {
name: 'Alice',
regular() {
setTimeout(function() {
console.log(this.name); // undefined(默认绑定到 global / undefined)
}, 100);
setTimeout(() => {
console.log(this.name); // 'Alice'(箭头函数捕获外层 regular 的 this)
}, 100);
}
};
手动绑定(赋值时用 bind 或包装)
当把对象方法赋给变量或传入回调时,this 容易丢失。可在赋值阶段就绑定:
const handleClick = obj.handleClick.bind(obj);-
const handleClick = () => obj.handleClick();(简洁但每次调用新建函数) - 类中常用属性初始化写法:
handleClick = () => { ... }(利用箭头函数自动绑定实例)
使用 call 模拟构造函数调用(较少见但可行)
虽然不常见,但可通过 Function.prototype.call 显式将 this 绑定到新对象上,模拟 new 行为:
function Person(name) {
this.name = name;
}
const p = {};
Person.call(p, 'Bob'); // p 被显式设为 this
console.log(p.name); // 'Bob'
不复杂但容易忽略:关键不在“怎么改”,而在“什么时候改”——只要函数脱离原对象调用,this 就可能变,默认绑定只是兜底行为;主动控制才是可靠做法。











