前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TypeScript系列教程八《类》

TypeScript系列教程八《类》

作者头像
星宇大前端
发布2021-07-23 16:06:40
5700
发布2021-07-23 16:06:40
举报
文章被收录于专栏:大宇笔记大宇笔记

TypeScript完全支持ES2015中引入的class关键字。 与其他JavaScript语言特性一样,TypeScript添加了类型注释和其他语法,允许您表达类和其他类型之间的关系。

类的成员


下面是一个空的类:

代码语言:javascript
复制
class Point {}

这个类现在毫无用处,现在往这个类里面加点成员

字段

在类上声明字段,编程了可读写的public 属性

代码语言:javascript
复制
class Point {
  x: number;
  y: number;
}

const pt = new Point();
pt.x = 0;
pt.y = 0;

属性初始化: 类实例化的时候,会初始赋值

代码语言:javascript
复制
class Point {
  x = 0;
  y = 0;
}

const pt = new Point();
// Prints 0, 0
console.log(`${pt.x}, ${pt.y}`);

与const、let和var一样,类属性的初始值设定项将用于推断其类型:

代码语言:javascript
复制
const pt = new Point();
pt.x = "0";
//Type 'string' is not assignable to type 'number'.

–strictPropertyInitialization

StricPropertyInitialization设置控制类字段是否需要在构造函数中初始化。

在这里插入图片描述
在这里插入图片描述

正常构建需要初始化:

代码语言:javascript
复制
class GoodGreeter {
  name: string;

  constructor() {
    this.name = "hello";
  }
}

不初始化使用!断言,也不会报错:

代码语言:javascript
复制
class OKGreeter {
    // Not initialized, but no error
    name!: string;
  }

readonly

只读属性,不多介绍,只能读取不能赋值。

注意:构造函数内可以赋值

代码语言:javascript
复制
class Greeter {
  readonly name: string = "world";

  constructor(otherName?: string) {
    if (otherName !== undefined) {
      this.name = otherName;
    }
  }

  err() {
    this.name = "not ok";
//Cannot assign to 'name' because it is a read-only property.
  }
}
const g = new Greeter();
g.name = "also not ok";
//Cannot assign to 'name' because it is a read-only property.

构造函数

类构造函数与函数非常相似。可以添加带有类型注释、默认值和重载的参数:

代码语言:javascript
复制
class Point {
  x: number;
  y: number;

  // Normal signature with defaults
  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  }
}
代码语言:javascript
复制
class Point {
  // Overloads
  constructor(x: number, y: string);
  constructor(s: string);
  constructor(xs: any, y?: any) {
    // TBD
  }
}

super 调用

如果有基类,必须在构造函数中调用super,且在使用this之前

代码语言:javascript
复制
class Base {
  k = 4;
}

class Derived extends Base {
  constructor() {
    // Prints a wrong value in ES5; throws exception in ES6
    console.log(this.k);
//'super' must be called before accessing 'this' in the constructor of a derived class.
    super();
  }
}

Methods

在类中函数属性统称为方法

代码语言:javascript
复制
class Point {
  x = 10;
  y = 10;

  scale(n: number): void {
    this.x *= n;
    this.y *= n;
  }
}
代码语言:javascript
复制
let x: number = 0;

class C {
  x: string = "hello";

  m() {
    // This is trying to modify 'x' from line 1, not the class property
    this.x = "world";
    x = 4 
// Type 'string' is not assignable to type 'number'.
  }
}

Getters / Setters

类也可以有访问器:

代码语言:javascript
复制
class C {
  _length = 0;
  get length() {
    return this._length;
  }
  set length(value) {
    this._length = value;
  }
}

注意,没有额外逻辑的字段支持的get/set对在JavaScript中很少有用。如果在get/set操作期间不需要添加额外的逻辑,那么公开公共字段就可以了。

TypeScript对访问器有一些特殊的推理规则:

  • 只有get 没有set ,这个属性自动变成raedonly
  • 如果set 的参数没有明确指出,那么按照get 类型推断
  • Getters and setters必须具有相同的成员可见性(public,private)
代码语言:javascript
复制
class Thing {
    _size = 0;

    get size(): number {
        return this._size;
    }

    set size(value: string | number | boolean) {
        let num = Number(value);

        // Don't allow NaN, Infinity, etc

        if (!Number.isFinite(num)) {
            this._size = 0;
            return;
        }

        this._size = num;
    }
}

索引签名

类可以声明索引签名;它们的工作方式与其他对象类型的索引签名相同:

代码语言:javascript
复制
class MyClass {
  [s: string]: boolean | ((s: string) => boolean);

  check(s: string) {
    return this[s] as boolean;
  }
}

因为索引签名类型还需要捕获方法的类型,所以很难有效地使用这些类型。一般来说,最好将索引数据存储在另一个地方,而不是类实例本身。

类的实现和继承

与其他具有面向对象特性的语言一样,JavaScript中的类可以从基类继承。

implements

一个类可以准守一个或者多个接口去实现它:

代码语言:javascript
复制
interface Pingable {
  ping(): void;
}

class Sonar implements Pingable {
  ping() {
    console.log("ping!");
  }
}

class Ball implements Pingable {
//Class 'Ball' incorrectly implements interface 'Pingable'.
  //Property 'ping' is missing in type 'Ball' but required in type 'Pingable'.
  pong() {
    console.log("pong!");
  }
}

类同时可以准守多个接口取实现,例如 class C implements A, B {

可选值不会要求,实现类去实现:

代码语言:javascript
复制
interface A {
  x: number;
  y?: number;
}
class C implements A {
  x = 0;
}
const c = new C();
c.y = 10;
Property 'y' does not exist on type 'C'.

extends (继承)

类可以从基类扩展。派生类具有其基类的所有属性和方法,还定义其他成员。

代码语言:javascript
复制
class Animal {
  move() {
    console.log("Moving along!");
  }
}

class Dog extends Animal {
  woof(times: number) {
    for (let i = 0; i < times; i++) {
      console.log("woof!");
    }
  }
}

const d = new Dog();
// Base class method
d.move();
// Derived class method
d.woof(3);

方法重写

子类继承父类之后,可以重写属性和方法

代码语言:javascript
复制
class Base {
  greet() {
    console.log("Hello, world!");
  }
}

class Derived extends Base {
  greet(name?: string) {
    if (name === undefined) {
      super.greet();
    } else {
      console.log(`Hello, ${name.toUpperCase()}`);
    }
  }
}

const d = new Derived();
d.greet();
d.greet("reader");

面向对象的特征父类可以指向子类(变量多态):

代码语言:javascript
复制
// Alias the derived instance through a base class reference
const b: Base = d;
// No problem
b.greet();
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-07-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 类的成员
    • 字段
      • readonly
        • 构造函数
          • super 调用
            • Methods
              • Getters / Setters
                • 索引签名
                • 类的实现和继承
                  • implements
                    • extends (继承)
                      • 方法重写
                      相关产品与服务
                      数据保险箱
                      数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档