目录
- 前言
- 五条绑定规则
- 1. 默认绑定(独立调用)
- 2. 隐式绑定(方法调用)
- 3. 显式绑定(call / apply / bind)
- 4. new 绑定(构造函数)
- 5. 箐头函数(词法绑定)
- 优先级排序(由高到低)
- 总结
前言
JavaScript 的this与 Java、Python 等语言不同,它的值不是在函数定义时确定的,而是在函数被调用时动态绑定的。
可以把this理解为函数执行时的"上下文对象"——指向"当前是谁在调用我"。
五条绑定规则
1. 默认绑定(独立调用)
当函数不是作为对象方法调用,也不是通过new、call/apply/bind调用时:
functionshow(){console.log(this);}show();// 非严格模式: window; 严格模式: undefined- 非严格模式:指向全局对象(浏览器
window,Nodeglobal) - 严格模式:指向
undefined
2. 隐式绑定(方法调用)
谁调用了函数,this就指向谁——即"点"前面的对象。
constobj={name:'Alice',greet:function(){console.log(this.name);}};obj.greet();// Alice(this 指向 obj)⚠️注意:赋值给变量再调用会"丢失 this"
constfn=obj.greet;fn();// undefined(独立调用,this 指向 window)3. 显式绑定(call / apply / bind)
手动强制指定this指向:
functionintroduce(age){console.log(this.name+' 今年 '+age+' 岁');}constperson={name:'Bob'};introduce.call(person,18);// Bob 今年 18 岁introduce.apply(person,[18]);// Bob 今年 18 岁(参数用数组)constboundFn=introduce.bind(person,18);boundFn();// Bob 今年 18 岁(bind 返回新函数)| 方法 | 参数形式 | 返回值 |
|---|---|---|
call | 逐个传递 | 立即执行 |
apply | 数组传递 | 立即执行 |
bind | 逐个传递 | 返回新函数 |
4. new 绑定(构造函数)
使用new调用函数时,JS 创建新对象,this指向该对象:
functionCar(model){this.model=model;}constmyCar=newCar('Tesla');console.log(myCar.model);// Tesla5. 箐头函数(词法绑定)
箭头函数没有自己的this,它会捕获定义时所在作用域的this,且call/apply/bind无法改变:
constobj={name:'Eve',greet:function(){// 普通函数:this 指向 windowsetTimeout(function(){console.log(this.name);// undefined},100);// 箭头函数:this 继承自外层(即 obj)setTimeout(()=>{console.log(this.name);// Eve},100);}};obj.greet();优先级排序(由高到低)
| 优先级 | 绑定类型 |
|---|---|
| 1(最高) | new绑定 |
| 2 | 显式绑定(call/apply/bind) |
| 3 | 隐式绑定(对象方法调用) |
| 4(最低) | 默认绑定 |
总结
记住一句话:除非使用箭头函数,否则
this永远指向"调用它的那个对象";如果不知道是谁调用的,就指向全局(严格模式下是undefined)。
掌握这条规则,再结合call/apply/bind能强行改变指向,就能解决绝大多数this问题。