JavaScript 中的 this

Java 的 this 存在于类的实例对象中,指向实例对象自身。然而在 JavaScript 中,并不存在严格意义上的类,那么它的 this 跟什么有关呢?很高兴和您一起学习和探讨。

this 是什么

this 是在函数被调用时 “注入” 进函数作用域里的。this 相当于函数作用域増持了一个属性[‘this’],跟其他属性是并列关系。它既不指向函数,不属于函数,又不指向函数作用域就显而易见了。

this 指向谁

既然 this 函数被调用时注入的,那么寻找 “函数被调用的位置” 就是我们的突破口,debugger; 或打断点是不错的选择。

window/global

上面例子中 foo() 注入的 this,global对象, 在浏览器则是window。(strict 模式下则是 undefined)

[obj].[func]

如果是 [obj].[func] 的形式,只绑定最后一层。存在 “this 丢失”。

const a = 1;
function foo() {
    console.log( this.a );
}
const obj = {
    a: 2,
    foo: foo,
};
foo();
obj.foo();
// 只绑定最后一层。
const parent = {
    a: 0,
    obj,
};
parent.obj.foo();
// "this" 丢失
const bar = obj.foo;
bar();

call/apply bind

优先级 bind > call/apply > [obj].[func]

const a = 1;
function foo() {
    console.log( this.a );
}
const obj = {
    a: 2,
    foo: foo,
};
const callOther = {
    a: 'call',
}
const bindOther = {
    a: 'bind',
}
// call/apply 优先级 比 [obj].[func] 高
obj.foo.call(callOther);
const func = foo.bind(bindOther);
func(); // "bind"
// bind 优先级 比 call/apply 高
func.call(callOther); // "bind"

bind 实际上是 call/apply 的语法糖

call / apply

参考

You-Dont-Know-JS