1. 沿着作用域向上找最近的一个 function(不是箭头函数),看这个 function 最终是**怎样执行**的;
2. this 的指向取决于所属 function 的调用方式,而不是定义;
function 调用一般分为以下几种情况:
- 作为函数调用,即:`foo()`,可以理解为 window.foo()
- 指向全局对象(globalThis),注意严格模式问题,严格模式下是 undefined
- 作为方法调用,即:`foo.bar()` / `foo.bar.baz()` / `foo['bar']()` / `foo[0]()`
- 指向最终调用这个方法的对象
- 作为构造函数调用,即:`new Foo()`
- 指向一个新对象 `Foo {}`
- 特殊调用,即:`foo.call()` / `foo.apply()` / `foo.bind()`
- 参数指定成员
如果找不到所属的 function,this 就指向全局对象
```javascript
function foo () {
console.log(this)
// this => anything
}
// foo() => globalThis / 全局
// const obj = { foo: foo }
// obj.foo() => obj
// foo.call(123) => 123
```
```javascript
const obj1 = {
foo: function () {
console.log(this)
}
}
// obj1.foo() => obj1
// const fn = obj1.foo
// fn() => globalThis
```
```javascript
// this 指向取决于当前这个 function 最终怎样被执行
const obj2 = {
foo: function () {
// console.log(this) => obj2
function bar () {
console.log(this) // this => globalThis
}
bar()
}
}
obj2.foo()
```
```javascript
var length = 10
function fn () {
console.log(this.length)
}
const obj = {
length: 5,
method (fn) {
fn() // this => undefield
// arguments => [fn, 1, 2]
// arguments[0] === fn // => true
arguments[0]() // 此时this指向arguments
}
}
obj.method(fn, 1, 2)
```
谢天谢地,以后再无 this 问题。。。