438 字
2 分钟
06 · this 的四种绑定
this 不是”谁调用”这么简单
新人常以为 this 指向”调用它的对象”。错。规则有优先级,记住四条并按顺序判断就不会乱。
四条绑定规则(优先级从低到高)
1. 默认绑定:独立调用,非严格模式指向 window,严格模式 undefined。
function foo() { console.log(this); }foo(); // 严格模式 undefined,否则 window2. 隐式绑定:作为对象方法调用,this 指向该对象。
obj.foo(); // this === obj⚠️ 隐患:把方法”抽出来”单独调用会丢失绑定(见下)。
3. 显式绑定:call / apply / bind 强行指定。
foo.call(obj, arg1); // 立即调用,this=objfoo.apply(obj, [arg1, arg2]); // 同上,参数数组const bar = foo.bind(obj); // 返回新函数,this 永久绑定 obj4. new 绑定:new Foo() 时,this 指向新创建的对象。
优先级
new > 显式(bind) > 隐式 > 默认。记忆口诀:new 最先,bind 次之,隐式再次,默认垫底。
箭头函数:没有 this
箭头函数不绑定自己的 this,而是继承外层词法作用域的 this:
const obj = { name: "Tom", friends: ["A", "B"], say() { this.friends.forEach(() => console.log(this.name)); // this 继承 say() 的 this },};这解决了回调里 this 丢失的老大难问题——以前得用 const self = this 或 bind。
小结
- 判断
this:先看是不是箭头函数(继承外层)→ 再看new→call/apply/bind→ 隐式 → 默认。 - 方法被抽离赋值再调用会丢失隐式绑定,用
bind或箭头函数解决。 - 箭头函数无
this,是回调场景的最佳选择。
练习
- 预测
obj.foo()与const f = obj.foo; f()的this差异并解释。 - 用
call实现一个sum的借用调用。 - 把一段用
const self = this的老代码改成箭头函数写法。
06 · this 的四种绑定
http://117.72.32.87/blog/posts/js-roadmap-06-this-binding/