隐式丢失就是指被绑定的函数丢失了绑定对象,从而默认绑定到 window 对象上
// 情况一:函数别名
const a = 0;
function foo() {
console.log(this.a);
}
const obj = {
a: 1,
foo: foo,
};
const bar = obj.foo();
console.log(bar()); // 0
// 把obj.foo赋值给别名bar,造成隐式丢失的情况,只是把obj.foo()赋值给了bar变量,而bar与obj对象毫无关系
// 情况二:参数传递
const a = 0;
function foo() {
console.log(this.a);
}
function bar(fn) {
fn();
}
const obj = {
a: 1,
foo: foo,
};
console.log(bar(obj.foo)); // 0
// 把obj.foo当成参数传递到bar函数中
// 情况三:内置函数
const a = 0;
function foo() {
console.log(this.a);
}
const obj = {
a: 1,
foo: foo,
};
setTimeout(obj.foo, 1000); // 0 this指向window
// 情况四:间接调用
function foo() {
console.log(this.a);
}
const a = 2;
const obj = {
a: 3,
foo: foo,
};
const p = { a: 4 };
(p.foo = obj.foo)(); // 2
// 将obj.foo函数对象赋值给p.foo函数,然后立即执行。相当于仅仅是foo()函数的立即调用,内部this默认指向了window
// 将obj.foo赋值给p.foo函数,之后p.foo()再执行,其实是属于p对象的方法的指向,this指向了当前的p对象
p.foo = obj.foo;
p.foo(); // 4
// 情况五:指向了window的特殊情况
const a = 0;
const obj = {
a: 1,
foo: foo,
};
function foo() {
console.log(this.a);
}
(obj.foo = obj.foo)(); // 0 实际是foo函数立即执行
(false || obj.foo)(); // 0
(1, obj.foo)(); // 0
总结
- 默认绑定
- 隐式绑定
- 显式绑定
- new 绑定
分别对应函数的四种调用:
- 独立调用
- 方法调用
- 间接调用(call,apply,bind)
- 构造函数调用
关于 this 指向问题可参考这篇博客:你还没搞懂 this?