this是JavaScript中的关键字,它可以表示调用函数的对象或者实例对象等。本文为朋友们介绍函数声明和函数表达式中this值的类型。
在默认情况下,编译器会将函数中的this值设置为any类型,并允许程序在this值上执行任意的操作。因为,编译器不会对any类型进行类型检查。例如,下例中在this值上的所有访问操作都是允许的:
function f() {
// 以下语句均没有错误
this.a = true;
this.b++;
this.c = () => {};
}
将this值的类型设置为any类型对类型检查没有任何帮助。因此,TypeScript提供了一个“--noImplicitThis”
编译选项。当启用了该编译选项时,如果this值默认获得了any类型,那么将产生编译错误;如果函数体中没有引用this值,则没有任何影响。
/**
* --noImplicitThis=true
*/
function f0() {
this.a = true; // 编译错误
this.b++; // 编译错误
this.c = () => {}; // 编译错误
}
// 没有错误
function f1() {
const a = true;
}
函数中this值的类型可以通过一个特殊的this参数来定义。
函数的this参数
TypeScript支持在函数形式参数列表中定义一个特殊的this参数来描述该函数中this值的类型。示例如下:
function foo(this: { name: string }) {
this.name = 'Patrick';
this.name = 0;
// ~~~~~~~~~
// 编译错误!类型 0 不能赋值给类型 'string'
}
this参数固定使用this作为参数名。this参数是一个可选的参数,若存在,则必须作为函数形式参数列表中的第一个参数。this参数的类型即为函数体中this值的类型。
this参数不同于常规的函数形式参数,它只存在于编译阶段,在编译生成的JavaScript代码中会被完全删除,在运行时的代码中不存在这个this参数。
如果我们想要定义一个纯函数或者是不想让函数代码依赖于this的值,那么在这种情况下可以明确地将this参数定义为void类型。这样做之后,在函数体中就不允许读写this的属性和方法。示例如下:
function add(this: void, x: number, y: number) {
this.name = 'Patrick';
// ~~~~
// 编译错误:属性 'name' 不存在于类型 'void'
}
当调用定义了this参数的函数时,若this值的实际类型与函数定义中的期望类型不匹配,则会产生编译错误。示例如下:
function foo(this: { bar: string }, baz: number) {
// ...
}
// 编译错误
// 'this'类型为'void',不能赋值给 '{ bar: string }' 类型的this
foo(0);
foo.call({ bar: 'hello' }, 0); // 正确
第1行,将foo函数this值的类型设置为对象类型“{ bar: string }”
。
第7行,调用foo函数时this值的类型为void类型,它与期望的类型不匹配,因此产生编译错误。
第9行,在调用foo函数时指定了this值为“{ bar: 'hello' }”
,其类型符合this参数的类型定义,因此不会产生错误。“Function.prototype.call()”
方法是JavaScript内置的方法,它能够指定调用函数时使用的this值。
酷客网相关文章:
评论前必须登录!
注册