一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
在 js 中this的指向是动态的, 在 ts 中就很纠结: 既要保留 js 的灵活又要进行严格的类型检查。ts: 我太难了。
js 中的 this 指向
大部分的时候, this 的指向取决于函数的调用方式。
const user = {
name: 'KinWen',
age: 18,
sayHello(){
console.log(`你好,我是${this.name}`);
}
}
- 如果直接调用函数(全局调用), this 指向全局或 undefined (启用严格模式)
const sayHello = user.sayHello;
sayHello(); // this指向全局对象
- 如果使用
对象.方法调用, this 指向对象本身。
user.sayHello(); // this指向user对象
- 如果是 dom 事件的处理函数, this 指向事件处理对象。
document.body.addEventListener('click',function () {
console.log(this); //this === body
})
特殊情况
- 箭头函数, this指向在函数声明是确定, 指向函数声明当前的this。
- 使用 bind apply call 手动更改 this 指向。
TS 中的 this 指向
在 ts 中 this 的类型检查默认为 any
为什么是 any 呢?
因为 ts 也不知道函数是以什么方式调用的
但是在大多数的情况下, 声明在对象上的方法, 都是通过对象.方法的方式调用的, 但是 ts 默认 this 的类型为 any, 为了 this 的指向正确, 可以在 tsconfig.json 中的 compilerOptions.noImplicitThis:true 开启这个属性的配置表示: 不允许 this 隐士的指向 any
开启之后就有 this 的提示了。
但是开启之后我仍然可以这样调用
const sayHello = user.sayHello;
sayHello(); //全局对象
这是不希望看见的, 为了避免这种不正确的使用方式可以配合接口对 this 的类型就行约束。
interface User {
name: string;
age: number;
sayHello(this: User): void
}
sayHello(this: User): void 在第一个参数的位置进行约束 this 的指向为 User, 约束之后就能避免错误的使用方式
总结
ts 对 this 的约束无法做到很全面的约束, 因为考虑到既要保留 js 的灵活又要加上类型检查示。