函数调用中this指向由调用方式决定,按优先级依次判定:1.箭头函数继承外层非箭头函数this;2.new调用指向新实例;3.显式绑定(call/apply/bind)以传入对象为准;4.对象方法调用时点号左侧对象为this;5.默认绑定:非严格模式指向全局,严格模式为undefined。

函数调用中 this 的指向不是看函数怎么写的,而是看它怎么被调用的。判定时按固定优先级逐层检查,不重叠、不跳过,只要匹配上就停止。
1. 先看是不是箭头函数
箭头函数没有自己的 this,直接沿用定义时外层第一个非箭头函数的 this 值。call/apply/bind 对它完全无效。
- const obj = { name: 'Alice', fn: () => console.log(this.name) }; obj.fn() → 输出 undefined(this 指向全局,不是 obj)
- 若外层是普通函数且 this 已绑定,则箭头函数继承该绑定
2. 再看是不是 new 调用
函数前加了 new,this 就一定指向新创建的实例对象,其他所有规则都被覆盖。
- function Person(n) { this.name = n; } const p = new Person('Bob'); → this 指向 p
- 即使该函数之前被 bind 过,new 调用也会忽略原绑定,改用新实例
3. 接着看有没有显式绑定
调用时用了 call、apply 或 bind,this 就按传入的第一个参数确定。
- fn.call(obj, 1, 2) → this 是 obj
- fn.bind(obj)(3) → this 固定为 obj,后续调用不可更改
- bind 两次只生效第一次,第二次无效
4. 然后看是否属于对象方法调用
只看调用时点号(.)或方括号([])左边的对象是谁——就是 this 所指。
- obj.method() → this 是 obj
- obj.nested.inner() → this 是 obj.nested,不是 obj
- let f = obj.method; f() → 已脱离对象,退化为默认绑定
5. 最后落到默认绑定
以上都不满足,就按执行模式决定:
- 非严格模式:this 指向全局对象(浏览器是 window,Node 是 global)
- 严格模式:this 是 undefined
- 常见陷阱:setTimeout(obj.fn, 100)、事件监听器直接传函数,都会触发默认绑定











