ts 函数及class 类型 函数重载及面向对象
函数的几种声明方式
//函数类型签名
function foo(name: string): number {
return name.length;
}
// 函数表达式1
const foo1 = function (name: string): number {
return name.length
}
// 函数表达式2
const foo2: (name : string) => number = name => name.length
函数表达式2可读性很差 一般不推荐这么使用,要么直接在函数中进行参数和返回值的类型声明,要么使用类型别名将函数声明抽离出来:
// 类型别名将函数声明抽离出来 type FuncFoo = (name: string) => number const foo3: FuncFoo = (name)=> name.length
void 和 undefined 返回类型
// void代表函数没有返回操作
function foo4(): void {
}
// undefined 类型是一个实际的、有意义的类型值,而 void 才代表着空的、没有意义的类型值
function foo5(): undefined {
return;
}
函数的默认可选参数 其余参数
// 在函数逻辑中注入可选参数默认值 可选参数必须位于必选参数之后
function foo6(name: string, age?: number) {
const inputAge = age ?? 18;
return name.length + inputAge
}
// 直接为可选参数声明默认值 有默认参数自然是可选参数
function foo7(name: string, age: number = 18): number {
const inputAge = age;
return name.length + inputAge
}
// rest 其余参数
function foo8(arg1: string, ...rest: any[]) { }
foo8('2')
// 元组方式定义
function foo9(arg1: string, ...rest: [number, boolean]) { }
foo9('1', 1, true)
函数重载
// 函数重载
function func1(foo: number, bar?: boolean): string | number {
if (bar) {
return String(foo);
} else {
return foo * 599;
}
}
// func1 进行重载 变成以下三个函数
/**
*
* function func(foo: number, bar: true): string,重载签名一,传入 bar 的值为 true 时,函数返回值为 string 类型。
* function func(foo: number, bar?: false): number,重载签名二,不传入 bar,或传入 bar 的值为 false 时,函数返回值为 number 类型。
* function func(foo: number, bar?: boolean): string | number,函数的实现签名,会包含重载签名的所有可能情况。
*/
function func(foo: number, bar: true): string;
function func(foo: number, bar?: false): number;
function func(foo: number, bar?: boolean): string | number {
if (bar) {
return String(foo);
} else {
return foo * 599;
}
}
func(1)
最后一个是实现签名包含了所有的签名情况。
上边都是是重载签名,是参数的某一种的可能性
异步函数、Generator 函数等类型签名
// 异步函数、Generator 函数等类型签名
async function asyncFunc(): Promise<void> { }
// 下边两个不常用
function* genFunc(): Iterable<void> { }
async function* asyncGenFunc(): AsyncIterable<void> { }
Promise 是 Promise 泛型的某种具体值
class类
//CLASS 以及修饰符
/**
* public / private / protected / readonly。
* 除 readonly 以外,其他三位都属于访问性修饰符,
* 而 readonly 属于操作性修饰符(就和 interface 中的 readonly 意义一致)
* public:此类成员在类、类的实例、子类中都能被访问。
* private:此类成员仅能在类的内部被访问。
* protected:此类成员仅能在类与子类中被访问,你可以将类和类的实例当成两种概念,即一旦实例化完毕(出厂零件),那就和类(工厂)没关系了,即不允许再访问受保护的成员。
*/
class Foo {
prop: string;
// 我们可以在构造函数中对参数应用访问性修饰符:此时,参数会被直接作为类的成员(即实例的属性),免去后续的手动赋值。
// 此时自动生成类属性 inputPop
constructor(public inputProp: string) {
this.prop = inputProp;
}
// 静态成员 不同于实例成员,在类的内部静态成员无法通过 this 来访问,需要通过 Foo.staticHandler 这种形式进行访问
static staticHandler() { }
protected print(addon: string): void {
console.log(`${this.prop} and ${addon}`)
}
public get propA(): string {
return `${this.prop}+A`;
}
// setter 方法不允许进行返回值的类型标注,
public set propA(value: string) {
this.prop = `${value}+A`
}
}
let fooSon = new Foo('11')
fooSon.propA = '11'
console.log(fooSon.propA,fooSon.inputProp); //11+A+A
注意点
- 静态成员直接挂载在函数体,实例成员挂载在原型 静态成员不会被实例继承,它始终只属于当前定义的这个类(以及其子类)。而原型对象上的实例成员则会沿着原型链进行传递,也就是能够被继承
继承 实现 抽象类
class Base {
print() { }
print2() { }
}
// 基类(Base) 与 派生类(Derived)
class Derived extends Base {
// 派生类对基类的覆盖
print() {
// 派生类对基类的访问
super.print()
}
// 我们覆盖方法时候无法保证 基类是否真的存在该方法, override则标识基类一定存在,否则重新方法报错
override print2() { }
}
// 抽象类
abstract class AbsFoo {
abstract absProp: string;
abstract get absGetter(): string;
abstract absMethod(name: string): string
}
//TypeScript 中无法声明静态的抽象成员。
// 我们必须完成实现这个抽象类的每一个抽象成员
class dtFoo implements AbsFoo {
absProp: string = '实现类'
get absGetter() {
return "linbudu"
}
absMethod(name: string) {
return name
}
}
// interface 不仅可以声明函数结构,也可以声明类的结构:
interface IDescription {
readonly name: string;
age: number;
male: boolean;
func?: Function
}
interface FooStruct {
absProp: string;
get absGetter(): string;
absMethod(input: string): string
}
class IFEFoo implements FooStruct {
absProp: string = "linbudu"
get absGetter() {
return "linbudu"
}
absMethod(name: string) {
return name
}
}
抽象类的实现
abstract 关键词抽象类
interface 接口来定义抽象类的结构
两者都得去实现抽象类里定义的每个属性和方法
私有构造函数
我们通常不会对类的构造函数进行访问性修饰,但是也有应用场景
// 私有构造函数用途
// 封装utils 方法类时,不希望使用者真的初始化这个类,而是直接调用静态方法,私有化构造函数会报错提醒
class Utils {
public static identifier = "linbudu";
private constructor() { }
public static makeUHappy() {
}
}
SOLID 原则
SOLID 原则是面向对象编程中的基本原则,它包括以下这些五项基本原则。