JavaScript 的 this 指向调用者而非定义时上下文;call/apply 立即执行并指定 this,bind 返回永久绑定新函数;箭头函数无 this,词法继承外层普通函数的 this;对象方法、事件回调等应避免使用箭头函数。

JavaScript 的 this 不是指向“函数定义时的上下文”,而是取决于“函数被谁调用”——这是所有指向问题的根源。
为什么 call、apply、bind 能改 this
它们直接干预函数执行时的调用上下文:
-
call(obj, arg1, arg2)立即执行,参数逐个传入 -
apply(obj, [arg1, arg2])立即执行,参数用数组传 -
bind(obj, arg1)返回新函数,this永久绑定为obj,后续调用无法覆盖
注意:bind 绑定后,再用 call 也无法改变其 this(箭头函数同理,但原因不同)。
箭头函数为何没有自己的 this
它不创建执行上下文,而是沿作用域链向上找外层普通函数的 this 值——本质是词法绑定。
立即学习“Java免费学习笔记(深入)”;
常见误用场景:
- 对象方法写成箭头函数:
obj = { fn: () => console.log(this) }→this指向全局或undefined(严格模式) - 事件回调中想访问实例,却用了箭头函数,结果
this不是组件实例
解决办法:对象方法、生命周期钩子、事件处理器,优先用普通函数声明。
定时器和回调里 this 丢失的典型表现
例如:setTimeout(obj.method, 100) 中,method 被单独提取为函数引用,调用时 this 指向全局(非严格)或 undefined(严格)。
可行修复方式:
- 用
bind:setTimeout(obj.method.bind(obj), 100) - 用箭头函数包裹:
setTimeout(() => obj.method(), 100) - 在类中提前绑定:
this.handleClick = this.handleClick.bind(this)(构造函数内) - 现代写法:类字段 + 箭头函数:
handleClick = () => { ... }(Babel / TS 支持)
最易忽略的一点:this 绑定发生在“调用时”,而不是“赋值时”或“传递时”。哪怕你把 obj.fn 赋给一个变量,再调用,也已经脱离了原对象——这个断连过程悄无声息,调试时得盯住调用形式。











