《五》大话 Typescript 函数与类

1,342 阅读4分钟

前言: 本文章为 TypeScript 系列文章. 旨在利用碎片时间快速入门 Typescript. 或重新温故 Typescript 查漏补缺.在官方 api 的基础上, 加上一些日常使用的感想. 如果感兴趣的话~ 欢迎关注, 后续持续推出文章.

文章列表:

目录结构:

  • 函数声明方式
  • 函数声明常见错误
  • 函数重载
  • 类的修饰符
  • 类声明常见错误

函数声明方式

直入正题, 下面介绍下四种函数定义的方法: TypeScript能够根据返回语句自动推断出返回值类型,因此我们通常省略它。

  1. 直接声明函数参数
function add(x:number, y: number) {
    return x + y;
}
  1. 在实际开发中, 函数调用经常会直接使用解构赋值的方式, 进而减少赋值. 这种场景的声明方式如下:
function add({ x, y }:{x: number, y: number}) {
    return x + y;
}
add({x: 2,y: 3}) 
  1. 声明剩余参数 剩余参数在使用的时候, 实际是一个数组. 按照这个思路, 我们只需要声明数组格式即可. 代码如下:
function add(...rest: number[]) {
    return rest.reduce((pre,cur) => pre+cur)
}
add(2, 3, 4, 5)
add('23',3) // 报错, 不能是字符串
  1. 在没有提供函数实现的情况下,有以下两种声明函数类型的方式:
type add = (x: number, y: number) => number;
interface add {
    (x: number, y: number):number
}

调用如下:

let addFn:add  = (a, b) => {
    return a + b
}

函数声明常见错误

必选参数不能位于可选参数后面. [题外话: 其实ts的错误提示特别明显,定位问题的时候仔细看往往就可以知道问题了]

// A required parameter cannot follow an optional parameter.
function add(x?: number,y: number) {
    return x + y;
} 

函数重载

这是一个不错的功能. 在很多大型库里面都可以看到函数重载这种方式. 使用他之后, 其他人看函数重载的个数便可知道函数里面的所有功能以及分支. 函数重载的方式如下, ts 会从一开始查找类型, 如果匹配就返回对应类型, 如果不匹配就到下一个

function add(x: string, y: string): string;
function add(x: number, y: number): number;
function add(x: any, y: any): any{
    if (typeof x === 'string') {
        return 'string';
    } else if(typeof x === 'number') {
        return x + y;
    }
}

比如看下面的代码:

从上面这块代码, 我们可以很清晰的得到,这个函数有以下几种调用方式:

  1. 只传 key
  2. 传 key, config
  3. 传 key , fn, config

tips: 维护一个公共组件时, 可使用这种方式让使用者和后面维护者快速知道函数的调用方式以及函数功能.

类的修饰符

类的修饰符扩展了原生js的一些功能特性,这个功能点非常好. 1、 公共,私有与受保护的修饰符.

class Greeter {
    constructor(message: string) {
        this.greeting = message;
    }
    
    greeting: string;
    readonly x: number; // 只读属性, 不可修改
    public greet() {
        return "Hello, " + this.greeting;
    }
    private hello() {
        return 'ee';
    }
    protected hi() {
        return 'ee';
    }
}

class children extends Greeter {
    constructor(m: string) {
        super(m);
    }

    test() {
        this.hello(); // 报错: 是私有成员, 不可在类外部调用
        this.hi(); // 可调用
    }
}
new children('333').greet()
new children('333').hello() // 报错: 是私有成员, 不可在类外部调用
new children('333').hi() //报错: 只能在子类中调用

总结以下上面的代码:

  1. private不能被子类调用, 不能在实例中访问,只能在声明类内部调用
  2. protected 只能在子类中调用, 不能在实例中访问
  3. public 都可以调用.

2、存取器 TypeScript支持通过getters/setters来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。

class Greeter {
    constructor(message: string) {
        this.greeting = message;
    }
    greeting: string;
    get hello() {
        return this.greeting;
    }
    set hi(x) {
        this.greeting = x;
    }
}
const x = new Greeter('eeee')
x.hi('22');
x.hello = '2' // 报错, 不能修改

实际上就是使用getters/setters来截取对对象成员的访问。解析出来的源码如下:

var Greeter = /** @class */ (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Object.defineProperty(Greeter.prototype, "hello", {
        get: function () {
            return this.greeting;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Greeter.prototype, "hi", {
        set: function (x) {
            this.greeting = x;
        },
        enumerable: true,
        configurable: true
    });
    return Greeter;
}());

3、静态属性

static 它是一个不用 new 就可以直接调用的方法.

class Greeter {
    constructor() {}
    static config: string = '33';
}
Greeter.config ='3'

类常见错误

若属性在 constructor 中声明可访问性了, 则不必在下面再声明一次.

class Dog {
    constructor(public name: string) {  
        // th.is.x = x
    }
    name: string; // 报错, Duplicate identifier 'name'. 重复声明
    eat() { }
}

总结

本篇文章介绍 typescript的函数和类, 类的修饰符在实际应用中有着广泛的应用,声明好一个类的私有成员, 公有成员,存取器, 可以让第三方调用更为安心.函数重载对于提高可读性也提供了很大的帮助.

  • 欢迎关注「前端加加」,认真学前端,做个有专业的技术人...