JavaScript中this的指向由函数调用方式决定:普通调用指向全局对象或undefined,对象方法调用指向点前对象,构造调用指向新实例,call/apply/bind显式绑定指定对象,箭头函数继承外层this。
JavaScript 中 this 的指向不是看函数怎么定义的,而是看它**怎么被调用的**——也就是函数执行时的调用方式决定了 this 绑定的对象。
绝大多数情况下,this 的值由函数调用时的「调用位置」和「调用语法」直接决定,和函数定义的位置、是否在对象里、是否嵌套无关。
foo()):非严格模式下 this 指向全局对象(浏览器是 window),严格模式下是 undefined
obj.method()
):this 指向调用它的那个对象(obj),注意只看「点前面是谁」new Foo()):this 指向新创建的实例对象call/apply/bind):this 被明确指定为第一个参数很多问题其实源于混淆了「定义」和「调用」:
const fn = obj.method; fn(); → 此时已脱离对象,this 不再是 obj
btn.addEventListener('click', obj.handler) → 点击触发时是 DOM 元素调用 handler,this 指向按钮,不是 obj
window 或 undefined)不是靠死记规则,而是用简单可靠的方式控制 this 行为:
.bind(obj)、或调用时用 func.call(obj, ...) / func.apply(obj, [...])
const self = this; 在外层保存,内层函数用 self 替代 this(兼容性好,但略显冗余)handler = () => { console.log(this); },天然绑定实例遇到不确定时,按顺序问自己三个问题:
new 调用的吗?→ 是:this 是新实例call/apply/bind 显式调用的吗?→ 是:this 是传入的第一个参数obj.fn())→ 是:this 是点前面的对象;否则就是普通调用(看严格模式)箭头函数跳过以上所有,直接取外层最近的非箭头函数的 this。