专栏首页全栈修仙之路TypeScript 函数中的 this 参数

TypeScript 函数中的 this 参数

从 TypeScript 2.0 开始,在函数和方法中我们可以声明 this 的类型,实际使用起来也很简单,比如:

function sayHello(this: void) {
  // this: void:表示在函数体内不允许使用this
}

在上面的 sayHello 函数中,this 参数是伪参数,它位于函数参数列表的第一位。为什么说 this 参数是伪参数呢?因为以上的 sayHello 函数经过编译后,并不会生成实际的参数,该函数编译成 ES5 后的代码如下:

function sayHello() {
  // this: void:表示在函数体内不允许使用this
}

那么在实际开发中,this 参数有什么用呢?下面我们来详细介绍一下 this 参数的一些应用场景。

一、未使用 this 参数

class Rectangle {
  private w: number;
  private h: number;

  constructor(w: number, h: number) {
    this.w = w;
    this.h = h;
  }

  getArea() {
    return () => {
      return this.w * this.h;
    };
  }
}

以上代码中,我们定义了一个 Rectangle 长方形类,该类中包含了两个私有的 w 和 h 属性,分别表示长方形的宽度和高度,此外还有一个 getArea 方法用于获取长方形的面积。在 getArea 方法中我们没有使用 this 参数,此时 this 的类型是 this,如下图所示:

二、使用 this 参数

class Rectangle {
  private w: number;
  private h: number;

  constructor(w: number, h: number) {
    this.w = w;
    this.h = h;
  }

  getArea(this: Rectangle) {
    return () => {
      return this.w * this.h;
    };
  }
}

与前面定义的 Rectangle 长方形类不同,在 getArea 方法中,我们使用了 this 参数,之后 this 的类型是 Rectangle 类型,如下图所示:

Rectangle 长方形类 getArea 方法中的 this 入参只是作为一个形式上的参数,供 TypeScript 做静态检查时使用,编译后并不会生成实际的入参。

三、禁止使用 this

有些时候,我们希望在方法中,禁止用户使用 this。针对这种需求,你可以设置 this 参数的类型为 void

class Rectangle {
  private w: number;
  private h: number;

  constructor(w: number, h: number) {
    this.w = w;
    this.h = h;
  }

  getArea(this: void) {
    return () => {
      return this.w * this.h;
    };
  }
}

以上代码会提示以下异常:

Property 'w' does not exist on type 'void'.
Property 'h' does not exist on type 'void'.

四、回调函数中 this

前端开发者日常经常需要跟回调函数打交道,比如在页面中监听用户的点击事件,然后执行对应的处理函数,具体示例如下:

const button = document.querySelector("button");
// ?. -> TS 3.7引入的可选链
button?.addEventListener("click", handleClick);

function handleClick() {
  console.log("Clicked!");
  // 'this' implicitly has type 'any' because it does not have a type annotation.
  this.removeEventListener("click", handleClick);
}

对于以上代码,TypeScript 编译器会有以下错误提示:this 隐式具有 any 类型,这是因为它没有类型注解。为了解决这个问题,我们就可以显式指定 this 参数的类型:

const button = document.querySelector("button");
button?.addEventListener("click", handleClick);

function handleClick(this: HTMLElement) {
  console.log("Clicked!");
  this.removeEventListener("click", handleClick);
}

除此之外,TypeScript 2.0 还增加了一个新的编译选项:--noImplicitThis,表示当 this 表达式值为 any 类型的时候,生成一个错误信息。

五、参考资源


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • RxJS Observable

    这两个模式是 Observable 的基础,下面我们先来介绍一下 Observer Pattern。

    阿宝哥
  • customElements 实战之 Lite-embed

    Lite-embed 的灵感来源于 paulirish 大神的 lite-youtube-embed 项目:

    阿宝哥
  • Angular DOM 抽象概述

    为了能够支持跨平台,Angular 通过抽象层封装了不同平台的差异,统一了 API 接口。如定义了抽象类 Renderer2 、抽象类 RootRenderer...

    阿宝哥
  • DedeCMS后台500错误一种原因是不支持PHP5.3、5.4及以上版本

      我们在迁移网站的时候,可能会出现DedeCMS后台500错误,有可能是因为dedecms不支持PHP5.3、5.4及以上版本,这时我们要改动一些设置才能修复...

    ytkah
  • Flutter第4天--基础控件(下)+Flex布局详解

    张风捷特烈
  • Flutter开发:TextField常用属性的使用

    在flutter开发过程中,掌握常用组件的使用是必备技能,flutter常用的组件和App开发时候常用的控件基本一模一样,只是使用的方式不一样罢了。

    三掌柜
  • TRTC学习之旅(三)-- 使用vue+ts集成互动直播

    上次我们已经用vue+ts实现了多人会议室的搭建,这次我们继续在上次项目的基础上,实现互动直播功能。

    黑眼圈云豆
  • 冬天到了,分享两款雪花特效代码

    小小鱼儿小小林
  • ActiveMQ源码分析——生产消息

    创建Session时,第一个传入是否开启事务,第二个传入session提交消费消息的方式 接下来看源码处理,生产者id对象由当前sessionID加上使用内部s...

    歪歪梯
  • ActiveMQ源码分析——消费消息

    请先查看上一篇分析生产消息源码的博客之后再查看本篇 先看看本博客把consumer端分析后完整的activemq流程图

    歪歪梯

扫码关注云+社区

领取腾讯云代金券