TypeScript基础篇 - TS类【Class】

目录

Class的基础

[Class 的定义](#Class 的定义)

重载

成员函数的重载

Getter/Setter

索引器

组合和继承

类的继承

推荐使用组合或者泛型

成员

类的成员可见域

静态成员【static】

类型的相等

类型守卫【ts做窄化】

抽象类

TS的类型一致(所谓的子类可以赋值给父类)

小结


Class的基础

Class 的定义

TypeScript 复制代码
class Point {
    // ts得先声明一下
    x: number
    y:number
    constructor(x: number, y: number) {
        this.x = x
        this.y = y    
    }
    public add(p: Point) : Point {
        return new Point(p.x + this.x, p.y + this.y)    
    }
}
const p = new Point(0, 0)
const newP = p.add(new Point(1, 1))
console.log(newP)

重载

成员函数的重载

TypeScript 复制代码
class Point4 {
  // ts得先声明一下
  x: number
  y: number
  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }
  // class中对成员函数进行重载
  public add(x: number, y: number): Point;
  public add(p: Point): Point;
  public add(x: number | Point, y?: number) {
    if (typeof x === 'number') {
        // 因为y是可选项,所有y: number | undefined;写作有!,
        // 让null和undefined可以赋值给其他类型并通过编译
      return new Point4(this.x + x, this.y + y!)
    }
    const p = x
    return new Point4(this.x + p.x, this.y + p.y)
  }
}
const p4 = new Point4(0, 0)
const newP4 = p4.add(new Point4(1, 1))
console.log(newP4)

Getter/Setter

TypeScript 复制代码
class C {
    _length = 0;
    // ES6语义
    get length() {
        return this._length;    
    }
    set length(value) {
        this._length = value;    
    }
}
TypeScript 复制代码
class C {
    _length = 0;
    // 函数语义
    getLength() {
        return this._length;    
    }
    setLength(value) {
        this._length = value;    
    }
}

索引器

TypeScript 复制代码
class Arr<T> {
    [i: number]: T // 索引器+类型标注
}
const a = new Arr<number>() // 索引器这个能力可以当成一个数组用,但是不常见
a[10] = 100
console.log(a[10]) // 100

组合和继承

类的继承

TypeScript 复制代码
class Animal {
    move() {
        console.log("Moving along!");    
    }
}
class Dog extends Animal{ // 继承,重度耦合;Dog.move
    woof(times: number) {
        for(let i = 0; i < times; i++) {
            console.log("woof!");        
        }    
    }
}

推荐使用组合或者泛型

TypeScript 复制代码
interface Movable { // 接口
    move() : void;
}
class Dog implements Movable { // 组合
    move() {
        console.log("move dog")    
    }
}
class Movable<T extends Animal> { // 泛型
    animal:T
    move() {
        console.log(`${animal.getName()} is moving`)    
    }
}

成员

类的成员可见域

  • public公开属性
  • protected保护属性
  • private私有属性
TypeScript 复制代码
class Point { 
    public x: number // public
}
// x可以被任意程序访问
TypeScript 复制代码
class Point {
    private x : number
    constructor() {
        this.x = x // 成立,x是私有的,只有自己的类里面可以用    
    }
    getX() {
        return this.x    
    }
}
const p = new Point()
console.log(p.x) // Error x是私有属性,只有在Point类里面可以用
console.log(p.getX()) // ok
TypeScript 复制代码
class Animal {
    private _name1;
    protected _name2;
}
class Dog extends Animal {
    getName1(){
        return this._name1 // Error 继承类也不能访问私有属性
    }
    getName2(){
        return this._name2 // pass 继承类可以访问保护属性
    }
}

静态成员【static】

TypeScript 复制代码
class MyClass {
    static x = 0; //静态成员
    static printX() {
        console.log(MyClass.x);    
    }
    static name = "S!"// Error name是静态成员的保留字,所以用不了
}
console.log(MyClass.x);
MyClass.printX();

类型的相等

类型守卫【ts做窄化】

TypeScript 复制代码
class FileSystemObject { // 文件系统的对象
    isFile(): this is FileRep { // 守卫:文件类型断言,触发类型窄化
        return this instanceof FileRep;    
    }
    isDirectory(): this is Directory {// 守卫:目录类型断言,触发类型窄化
        return this instanceof Directory;    
    }
    isNetworked(): this is Networked & this {// 守卫:域名类型断言,触发类型窄化
        return this.networked;    
    }
    constructor(public path: string, private networked: boolean) {}
}
class FileRep extends FileSystemObject {
    constructor(path: string, public content: string) {
        //super()相当于FileRep.prototype.constructor.call(this)
        super(path, false)            
    }
}
class Directory extends FileSystemObject {
    children: FileSystemObject[];
}
const fso: FileSystemObject = new FileRep("foo/bar.txt", "foo");
is(fso.isFile()) { // 文件
    fso.content;
    // const fso: FileRep
} else if (fso.isDirectory()) { // 目录
  fso.children;
  // const fsoL:Directory  
} else if (fso.isNetworked()) { // 地址
    fso.host;
    // const fso:Networked & FileSysremObject
}

抽象类

如果抽象类中没有具体方法,全都是抽象方法,那就等价于interface接口

TypeScript 复制代码
abstract class Base { // 抽象类 TS独有,JS中没有
// 抽象类不能实例化,只能继承
  abstract getName(): string;
  printName() {
    console.log("Hello," + this.getName());
  }
}
// 无法创建抽象类的实例
const b = new Base();
class Derived extends Base {
    // 继承抽象类,要实现一下继承过来的抽象类中的抽象方法 abstract getName()
    getName() {
        return "world";    
    }
}
const d = new Derived();
d.printName();

TS的类型一致(所谓的子类可以赋值给父类)

TypeScript 复制代码
class Point1 {
    x = 0;
    y = 0;
}
class Point2 {
    x = 0;
    y = 0;
}
// OK 对于typescript来说,相同的结构,就是同一类型,
// TS检查,发生在编译时,做静态类型检查,看的就是静态成员是否一致
const p : Point1 = new Point2(); 
TypeScript 复制代码
class Person {
    name: string;
    age:number;
}
class Employee {
    name: string;
    age:number;
    salary: number;
}
// OK TS是按成员来分辨是否是继承,像上面这种,TS认为是隐形的继承
// Employee比Person多一个成员,认为 class Employee extends Person {}
const p: Person = new Employee();

小结

  • TS如何判断类型的一致?代价如何?基于实际的每一项成员是否一致判断的。代价可以承担,就是慢点,而且发生在编译时。真正运行时,是不会有ts代码的,也不会帮我们生成新的代码不占我们的性能
  • 在Class的使用中,TS有实现JS没有的能力吗?没有,去掉ts部分依然可以运行,ts只有少量的是js没有的,如枚举
相关推荐
喵叔哟27 分钟前
重构代码之取消临时字段
java·前端·重构
还是大剑师兰特1 小时前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解1 小时前
【深度解析】CSS工程化全攻略(1)
前端·css
一只小白菜~1 小时前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding1 小时前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
阿征学IT1 小时前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓1 小时前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
丶21361 小时前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web
发现你走远了1 小时前
『VUE』25. 组件事件与v-model(详细图文注释)
前端·javascript·vue.js
Mr.咕咕1 小时前
Django 搭建数据管理web——商品管理
前端·python·django