1. 过去的一个原则
一般的函数this 的值取决于函数的调用方式而不是创建方式。this 可以看做函数的隐藏参数
从函数调用方式来看
- 通过对象调用,this 指向对象
- 在 a 对象创建,b 对象调用,this 仍然指向 b
- 不是通过对象调用,
- 没有 access 任何值则 this 指向globalThis或者 undefined
- 跟在一个primitive值后面,则 this 指向 primitive 对象或者 object 对象
回调函数的 this 问题
- 函数作为一个回调函数 this 的值取决于回调的调用方式,这由 API 的实现者确定。 由于整体的黑盒,所以我们对于一些函数this 的指向很模糊,需要知道一些常见的回调函数的 this 指向。
- 某些 API 允许为回调的调用设置 this 值。
[1, 2, 3].forEach(logThis, { name: "obj" });
特殊的回调函数
- DOM 事件处理程序
- this 参数将绑定到放置侦听器的 DOM 元素(使用 addEventListener()添加的侦听器
- this === e.currentTarget
- 内联事件处理程序
- this 将绑定到放置侦听器的 DOM 元素
2. 现在的一些改造
由于 callback 的 this 指向是由 api 实现者确定的,可能考虑并不全面。 因此我们需要确保 this 的指向是在创建过程中决定的。 有如下一些方法
-
箭头函数
- 箭头函数在其周围范围的 this 值上创建一个闭包,这意味着箭头函数的行为就像它们是 “自动绑定” 的——无论它如何调用,这都会绑定到创建函数时的状态
-
bind方法
- f.bind(someObject) 会创建一个与 f 具有相同主体和范围的新函数,但无论该函数如何调用,this 的值都会永久绑定到 bind 的第一个参数。
3. 关于面向对象的一些 this 方法
-
构造函数
- 当一个函数被 new 关键词修饰的时候他就是一个构造函数
- 无论在哪个对象上访问构造函数,其 this 都会绑定到正在构造的新对象
-
plainObj 的get 和 set方法
- 用作 getter 或 setter 的函数的 this 绑定到所设置或获取属性的对象。