TypeScript(ts)笔记总结01

3 篇文章 0 订阅
3 篇文章 0 订阅

 一、基础类型

// 基础类型
(() => {
    // 布尔类型-----boolean
    //  let 变量名:数据类型 = 值
    let flag: boolean = true;
    console.log(flag);
    // 数字类型------------number
    let a1: number = 10; //十进制
    let a2: number = 0b1010; //二进制
    let a3: number = 0o12; //八进制
    let a4: number = 0xa; //十六进制
    console.log(a1, a2, a3, a4);
    // 字符串类型---------string
    let str1 = 'str1';
    let str2 = 'str2';
    console.log(`${str1}=========${str2}`);
    // 字符串与数字类型拼接,隐式转换为字符串类型
    console.log(str1 + a1);

    // undefined 和 null 都可以作为其他类型的子类型,把undefined和null赋值给其他类型的变量,注意要在tsconfig.ts关闭严格模式strict
    let und: undefined = undefined;
    let nul: null = null;
    // let num:number = null
    console.log(und, nul);
    // console.log(num);

    // 数组类型
    // 方式1:let 变量名:数据类型[] = [值1,值2,值3]
    let arr1: number[] = [10, 20, 30];
    console.log(arr1);
    // 方式2:泛型写法:
    // 语法: let 变量名:Array<数据类型> = [值1,值2,值3]
    let arr2: Array<number> = [11, 12, 13];
    console.log(arr2);
    // 注意:数组定义后,里面的数据类型必须都一致,否则会报错

    //  元组类型:在定义数组的时候,类型和数据个数是一开始就已经限定,类型和位置都必须一一对应
    let arr3: [string, number, boolean] = ['lemon', 666, true];
    console.log(arr3);
    console.log(arr3[0].split(''));
    console.log(arr3[1].toFixed(2));

    // 枚举类型:枚举里面的每一个数据值都可以叫元素,每一个元素都有自己的编号,编号是从0开始的,依次的递增加1
    enum Color {
        red = 1,
        green,
        blue,
    }
    // 定义一个Color的枚举类型的变量来接收枚举的值
    let color: Color = Color.red;
    console.log(color, Color.red, Color.green, Color.blue, Color[3]);
    // 枚举中的元素可以是中午的数据值,但是不推荐
    enum Gender {
        男,
        女,
    }
    console.log(Gender.男, Gender[1]);

    // any 类型
    let str: any = 100;
    str = 'any--';
    console.log(str);
    // 当应该数组中要存储多个数据,个数不确定、类型不确定,此时也可以使用any类型来定义数组
    let arr: any[] = [100, 'any-arr', true];
    console.log(arr);
    console.log(arr[1].split(''));
    // 对于错误的书写也不会有报错信息提示,即any是放弃类型判断的
    // console.log(arr[0].split(''));

    // void类型,在函数声明的时候,小括号的后面使用 :void,代表的是该函数没阳任何返回值
    function showMsg():void {
        return   //输出undefined
        // return undefined //输出undefined
        // return null //报错:不能将类型“null”分配给类型“void”
    }
    console.log(showMsg());
    // 定义void类型的变量,也可以接收一个undefined的值,但没必要
    let vd:void = undefined
    console.log(vd);
    
    // object类型
    // 定义一个函数,参数是object类型,返回值也是object类型
    function getObj(obj:object):object {
        return {
            name:'lemon',
            age:18
        }
    }
    console.log(getObj({name:'lem',age:1}));

    // 联合类型(union Types)表示取值可以为多种类型中的一种
    // 需求1:定义一个函数得到一个数字或者是字符串值的字符串形式
    function getString(str:number|string):string {
        return str.toString()
    }
    console.log(getString(123));
    
    // 需求2:定义一个函数得到一个数字或字符串值的长度
    // 类型断言:告诉编译器,我指的是什么类型
    // 类型断言语法1: <类型>变量名  
    // 类型断言语法2: 值 as 类型
    function getString2(str:number|string):number {
        // return str.toString().length
        if ((<string>str).length) {
            // return (<string>str).length
            return (str as string).length
        } else {
            return str.toString().length
        }
    }  
    console.log(getString2(123456));
    console.log(getString2('lemon'));

    // 类型推断:在没有明确指定类型时,推测出一个类型
    let tx = 100 //number类型
    // tx = 'lemon-tx'  // 报错:不能将类型“string”分配给类型“number”。
    let tx2;  //any类型
    tx2 = 100
    tx2 = 'lemon-tx2'
    console.log(tx2);
    
})();

二、接口

// 接口时对象的状态(属性)和行为(方法)的抽象(描述)
// 接口:是一种类型、一种规范、一种规则一种能力、一种约束
(() => {
    // 需求:创建人的对象,需对人的属性进行一定的约束
    // id:number类型,必须,只读
    // name:string类型,必须
    // age:number类型,必须
    // sex:string类型,可以没有

    // 定义一个接口,该接口作为person对象的类型使用,限定或者是约束该对象的的属性数据
    interface IPerson {
        // readonly:只读属性 id是只读的,是number类型
        readonly id: number;
        name: string;
        age: number;
        //  ? 可有可无
        sex?: string;
    }
    // 定义一个对象,该对象的类型就是定义的接口IPerson
    const person: IPerson = {
        id: 1,
        name: 'lemon',
        age: 18,
        // sex: '女',  //sex可以没有
    };
    console.log(person);
    person.sex = '女';
    // person.id = 101; //无法分配到 "id" ,因为它是只读属性
    console.log(person.sex);
})();

 三、函数类型

// 为了使用接口表示函数类型,我们需要给接口定义一个调用签名
// 就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型
(() => {
    // 函数类型:通过接口的方式作为函数的类型来使用
    interface ISeachFunc {
        // 定义一个调用签名
        (source: string, subString: string): boolean;
    }
    // 定义一个函数,该类型就是上面定义的接口
    const searchString:ISeachFunc = function (source:string,subString:string):boolean {
        // 在source字符串中查找subString这个字符串
        return source.search(subString) > -1
    }
    // 调用函数
    console.log(searchString('lemon','mon'));
    
})();

四、类类型

// 类 类型:类的类型可以通过接口来实现
(()=>{
    // 定义一个接口
    interface IFly {
        // 该方法没有任何的实现(方法中什么都没有)
        fly()
    }
    // 定义一个类,这个类的类型就是上面定义的接口(实际上也可以理解为,IFly接口约束了当前的这个Person类)
    class Person implements IFly {
        // 实现接口中的方法
        fly() {
            console.log('lemon--fly');
        }
    }
    // 实例化对象
    const person = new Person()
    person.fly()

    // 定义一个接口
    interface Iswim {
        swim()
    }

    // 定义一个类,这个类的类型就是IFly和Iswim(当前这个类可以实现多个接口,一个类同时也可以被多个接口进行约束)
    class Person2 implements IFly,Iswim {
        fly() {
            console.log('lemon--fly2');
        }
        swim() {
            console.log('lemon--swim2');
        }
    }
    // 实例化对象
    const person2 = new Person2()
    person2.fly()
    person2.swim()

    // 总结:类可以通过接口的方式来定义当前的这个类的类型
    // 类可以实现一个接口,类也可以实现多个接口,但是接口中的内容都要真正的实现

    // 定义一个接口,继承其他多个接口
    interface IMyFlyAndSwim extends IFly,Iswim {}
    // 定义一个类,直接实现IMyFlyAndSwim这个接口
    class Person3 implements IMyFlyAndSwim {
        fly() {
            console.log('lemon--fly3');
        }
        swim() {
            console.log('lemon--swim3');
        }
    }

    const person3 = new Person3();
    person3.fly()
    person3.swim()
    // 接口和接口间:继承(extends),类和接口间:实现(implements)
})()

 五、类

// 类:可以理解为模板,通过模板可以实例化对象
// 面向对象的编程思想
(() => {
    // ts中类的定义及使用
    class Person {
        // 定义属性
        name: string;
        age: number;
        sex?: string;
        // 定义构造函数:为将来实例化对象的时候,可以对属性的值进行初始化
        constructor(name: string = 'lemon', age: number = 18, sex: string = '女') {
            // 更新对象中的属性数据
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
        // 定义实例方法
        sayHi(str: string) {
            console.log(`hi~,大家好,我是${this.name},今年${this.age},我是${this.sex}孩子`, str);
        }
    }
    // ts中使用类,实例化对象,可以直接进行初始化操作
    const person1 = new Person();
    const person2 = new Person('小姜', 20, '男');
    person1.sayHi('你呢?')
    person2.sayHi('很高兴认识你')
})();

六、继承

// 继承:类与类之间的关系
// 继承后类与类之间间的父子关系叫法:
// A类继承了B这个类,那么此时A类叫字类,B类叫基类
// 子类 ---》派生类
// 基类 ---》超类(父类)
(() => {
    // 定义一个类,作为基类(超类/父类)
    class Person {
        // 定义属性
        name: string; //姓名
        age: number;
        sex: string;
        // 定义构造函数
        constructor(name: string = 'lemon', age: number = 18, sex: string = '女') {
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
        // 定义实例方法
        sayHi(str: string) {
            console.log(`hi~,${this.name},${str}`);
        }
    }
    // 定义一个类,继承自Person
    class Student extends Person {
        constructor(name: string, age: number, sex: string) {
            // 调用的父类的构造函数,使用的是super
            super(name, age, sex);
        }
        // 可以调用父类的方法
        sayHi() {
            console.log('我是Students类中的sayHi方法');
            // 调用父类sayHi方法
            super.sayHi('你好!我是Person类中的sayHi方法');
        }
    }
    // 实例化Person
    const person1 = new Person();
    person1.sayHi('很高兴认识你');
    // 实例化Student
    const student1 = new Student('小姜', 20, '男');
    student1.sayHi();

    // 总结:类和类之间如果要继承关系,需要用使用extends关键字
    // 子类中可以调用父类中的构造函数,使用的是super关键字(包括调用父类中的实例方法,也可以使用super)
    // 子类中可以重写父类的方法
})();

七、多态

// 多态:父类型的引用指向了子类型的对象,不同类型的对象针对相同的方法,产生了不同的行为
(() => {
    // 定义一个类
    class Animal {
        // 定义一个属性
        name: string;
        // 定义一个构造函数
        constructor(name: string) {
            // 更新属性值
            this.name = name;
        }
        // 实例方法
        run(distance: number = 0) {
            console.log(`${this.name}跑了${distance}米的距离`);
        }
    }
    // 定义一个字类
    class Dog extends Animal {
        // 构造函数
        constructor(name:string){
            // 调用父类的构造函数,实现子类中属性的初始化操作
            super(name)
        }
        // 实例方法,重写父类中的实例方法
        run(distance: number=5) {
            console.log(`${this.name}跑了${distance}米的距离`);
        }
    }
    // 定义另一个字类
    class Pig extends Animal {
        // 构造函数
        constructor(name:string){
            // 调用父类的构造函数,实现子类中属性的初始化操作
            super(name)
        }
        // 实例方法,重写父类中的实例方法
        run(distance: number=10) {
            console.log(`${this.name}跑了${distance}米的距离`);
        }
    }
    // 实例化父类对象
    const ani:Animal = new Animal('动物');
    ani.run()
    // 实例化子类对象
    const dog:Dog = new Dog('小狗🐕');
    dog.run()
    // 实例化子类对象
    const pig:Pig = new Pig('小猪🐖');
    pig.run()
    console.log('-----------------------------------------------');
    // 父类和子类的关系:父子关系,此时父类类型创建子类的对象
    const dog1:Animal = new Dog("🐕")
    dog1.run()
    const pig1:Animal = new Pig("🐖")
    pig1.run()
    
    console.log('==================================================');
    // 该函数需要的参数是Animal类型的
    function showRun(ani:Animal) {
        ani.run()
    }
    showRun(dog1)
    showRun(pig1)
    
})();

八、修饰符

// 修饰符(类中成员的修饰符):主要是描述类中的成员(属性、结构函数,方法)的可访问性
// 类中的成员都有自己的默认的访问修饰符,public
// public修饰符--公共的,类中的成员默认的修饰符,代表的是公共的,任何位置都可以访问类中成员
// privite修饰符---私有的,类中的成员如果使用private来修饰,那么外部是无法访问这个成员数据的,当然子类中的也是无法访问该成员数据
// protected修饰符---受保护的,类中的成员如果使用protected来修饰,那么外部是无法访问这个成员数据的,但是子类是可以访问该成员数据

(() => {
    // 定义一个类
    class Person {
        // 属性
        // public name:string
        // private name:string
        protected name: string;
        // 构造方法
        constructor(name: string) {
            // 更新属性
            this.name = name;
        }
        // 方法
        public eat() {
            console.log('hi', this.name);
        }
    }
    // 定义一个字类
    class Student extends Person {
        constructor(name: string) {
            super(name);
        }
        play() {
            console.log(this.name,'喜欢玩球');
        }
    }
    // 实例化对象
    const per = new Person('lemon');
    // 类的外部可以访问类中的属性成员
    // console.log(per.name);
    per.eat();
    const stu = new Student('xj')
    stu.play()
    // console.log(stu.name);
})();

九、readonly修饰符

// readonly修饰符:实现是一个关键字,对类中的属性成员进行修饰,被修饰后的属性成员就不能在外部被随意的修改
// 构造函数中,可以对只读的属性成员数据进行修改,普通方法则不能
// 如果构造函数中没有任何参数,类中的属性成员此时已经使用readonly进行修饰,那外部也是不能对这个属性值进行更改的
// 构造函数中的参数可以使用readonly进行修饰,一旦修饰了,那该类中就有这个只读成员属性了,外部可以访问但是不能修改
// 构造函数中的参数可以使用public及private和protected进行修饰,无论是哪个进行修饰,该类中都会自动添加相应的属性成员
(() => {
    // readonly 修饰类中的成员属性操作
    // 定义一个类型
    class Person {
        // 属性
        readonly name: string;  //初始值
        // 构造函数
        constructor(name:string='小刘') {
            this.name = name;  // 构造函数中,可以对只读的属性成员数据进行修改
        }
        sayHi() {
            // 类中的普通法方法也是不能修改readonly修饰的成员属性值(一旦实例化就不能被修改了)
            //this.name = 'xj'
            console.log('hi~', this.name);
        }
    }
    // 实例化对象
    const person1 = new Person('lemon') 
    person1.sayHi()

    // 修改属性
    // person1.name = 'xj' //无法分配到 "name" ,因为它是只读属性。
    console.log(person1);
    console.log(person1.name);

    // readonly修饰类中的构造函数参数(参数属性)
    class Animal {
        // 构造函数中的参数,一旦使用readonly修饰,那么该参数就叫参数属性,
        // 此时Animal类中就相当于已经有了name的属性成员,外部无法修改类中的name属性成员值
        // constructor(readonly name:string = '小黑'){
        //     this.name = name
        // }
        // public修饰,那么Animal类中就相当于已经有了公共的name的属性成员
        // constructor(public name:string = '小黑'){
        //     this.name = name
        // }
        // private修饰,那么Animal类中就相当于已经有了私有的name的属性成员
        // constructor(private name:string = '小黑'){
        //     this.name = name
        // }
         // protected修饰,那么Animal类中就相当于已经有了受保护的name的属性成员
         constructor(protected name:string = '小黑'){
            this.name = name
        }
    }    
    // 实例化对象
    const ani = new Animal('小白')
    console.log(ani);
    // console.log(ani.name);
})();

 十、静态属性

// 静态成员:在类中通过static修饰的属性和方法(静态的属性及静态的方法)
// 静态成员在使用的时候是通过 类名. 的这种语法使用
(() => {
    // 定义一个类
    class Person {
        age: number;
        // 类中默认有一个内置的name属性,所以不能用name
        // 静态属性
        static name1: string = 'lemon';
        // 构造函数是不能用static来修饰的
        constructor(age: number = 18) {
            // 此时this是实例对象,name1是静态属性,不能通过实例对象直接调用静态属性来使用
            // this.name1 = name1
            this.age = age;
        }
        sayMx() {
            console.log('摩西摩西');
        }
        // 静态方法
        static sayHi() {
            console.log('Hi~');
        }
    }
    // 实例化对象
    const person1 = new Person(19);
    // 通过实例化对象调用属性(实例属性)
    console.log(person1.age);
    // 通过实例化对象调用的方法(实例方法)
    person1.sayMx();
    console.log('-----------------------------------------------');

    // 通过类名.静态属性 的方法来方法该成员数据
    console.log(Person.name1);
    // 通过类名.静态属性 的方法来修改该成员数据
    Person.name1 = '小刘';
    console.log(Person.name1);
    // 通过类名.静态属性 的方法来调用内部的静态方法
    Person.sayHi();
})();

十一、抽象类

// 抽象类:包含抽象方法(没有具体内容的实现),也可以包含实例方法,抽象类是不能被实例化的,为了让子类进行实例化及实现内部的抽象方法
// 抽象类的作用(目的):为子类服务
(() => {
    // 定义一个抽象类
    abstract class Animal {
        // 抽象属性:一般不写,没有必要再抽象类中写一个抽象属性
        // abstract name: string;
        // 抽象方法:没有方法体,不能有具体的实现
        abstract eat();
        // 实例方法
        sayHi() {
            console.log('摩西摩西');
        }
    }
    // 定义一个子类(派生类)
    class Dog extends Animal {
        // name: string='xx';
        // 重新实现抽象类的方法,此时这个方法就是Dog类的实例方法
        eat() {
            console.log('吃罐头');
        }
    }

    // 实例化Dog类
    const dog1 = new Dog();
    // console.log(dog1.name);
    dog1.eat();
    dog1.sayHi();
})();

 

 

注:出自B站尚硅谷Vue.JS教程快速入门到项目实战视频的笔记总结,感谢~~~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值