美文网首页
2020-10-30Typescript(1.2)

2020-10-30Typescript(1.2)

作者: 夏天的风2020 | 来源:发表于2020-11-02 13:45 被阅读0次

    Typescript: 进入类型的世界

    编程语言的类型:

    1.动态类型语言 (Dynamically Typed Language)
        指的是在运行期间才会做数据类型检查的语言,
        在用动态类型语言编程的时候,不用给变量指定数据类型,一个变量可以是字符串,你也可以给它赋值变成一个数字,非常灵活
        第一次赋值给变量的时候,在内部将数据类型记录下来
        比如javascript,
        也就是说javascript写好的程序只有我们在运行的时候才能发现有啥错误,这种做法听起来有点危险
        所以前端发明了一系列静态类型代码的检查器,
        比如eslint,在编码期间就可以根据一系列的规则,提示一些有问题地方
    
    
     2.静态类型语言(Statically Typed Language)
        数据类型检查发生在编译的阶段,也就是所写程序要声明变量的数据类型。
        写程序要声明数据类型
        比如c,c++,java
    
    

    TypeScript究竟是什么:

     Type指类型
        script指javascript,
        它的目标是把不看重类型的动态语言变成关注类型的静态语言
        1.官网口号javascript that scales可以理解为可扩展的javascript
        2.静态类型风格的类型系统
        3.从es6到es10甚至是esnext的语法支持
        4.兼容各种浏览器,各种系统,各种服务器,完全开源
    
    
    
        TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,
        因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,
        TypeScript 通过类型注解提供编译时的静态类型检查。
    
    

    为什么要学习typescript?

       1.程序更加容易
           函数或者方法输入输出的参数类型,外部条件等,
           动态语言的约束:需要手动调试等过程,
           有了typeScript:代码本身就可以回答上诉问题 
        2.效率更高
           在不同的代码块和定义中进行跳转
           代码自动保全
           丰富的接口提示
        3.更少的错误
           编译期间能够发现大部分错误
           杜绝大部分错误
    
    

    安装typescript

       查看node及npm版本
        node -v  (至少10以上)
        npm -v
    
        安装:npm install -g typescript  (可以指定版本安装)
        查看版本:  tsc -v
        ts文件转换成js文件:  tsc filnaem.ts
    
    

    # 函数

    Typescript 文档地址:Functions

     在javascript中函数是一等公民,
        函数和其他类型的公民都一样,
        可以作为参数,可以存入数组,可以被另外一个函数返回,可以被赋值给另外一个变量
        
        由两部分构成:
        输入:传参来实现
        输出: 就是函数的返回结果
    
    // 来到我们的第一个例子,约定输入,约定输出
    function add(x: number, y: number): number {
      return x + y
    }
    add(1,2)  //参数必须按照规定类型添加
    let result = add(1,2) //result也会变成number类型
    
    // 可选参数(加个问号)
    //在可选参数后面不可以再添加确定参数了,这样程序的判断就会发生混乱
    function add(x: number, y: number, z?: number): number {
      if (typeof z === 'number') {
        return x + y + z
      } else {
        return x + y
      }
    }
     //函数的表达式
     const add = (x:number,y:number,z?:number): number =>{
          if(typeof z === 'number'){
            return x+y+z
          }else{
           return x+ y
          }
       }
        //鼠标移到add上边,add获得了一个类型,
        //所以说,一个函数不仅输入和输出有类型,函数本身也是有类型的,
        //add是函数类型,
        //let add2: string = add  //会报错  函数类型和string类型是不适配的,
        //所以我们要声明一个完全一样的类型,
    
        在typescript中我们要这么写函数的类型,
        let add2: (x: number, y: number, z?:number) => number
        //(这个箭头不是es6的箭头函数,而是ts中声明函数类型返回值的方法。)
        //这个时候我们就是声明add2是number类型,
    
        //这个时候它们类型是一样的:let add2: (x: number, y: number, z?:number) => number = add  
        //不会报错
    
    
        //在ts中 凡是在冒号后面都是在声明类型,和实际的代码逻辑没什么关系
    
    
    // 函数本身的类型
    const add2: (x: number, y: number, z?:number) => number = add
    
    Interface---Duck typing的概念可以描述各种类型,
    它可以描述函数的类型么?
    声明一个函数类型
    
    
    // interface 描述函数类型
    interface ISum {
      (x: number, y: number): number  //在Interface返回使用的是冒号
    }
    const sum2: ISum = sum
    //(对比一下)
    let add2: (x: number, y: number, z?:number) => number  //直接写返回使用的是箭头
    
    //这时我们将add给它赋值为类型为ISum,类型也是完全的匹配
     let ada2: ISum = add
    
    

    类 - Class

     在javascript的世界我们使用构造函数和原型链来实现继承,
     到了es6时代,总算出现了class的概念,虽然它的内部还是原型链的机制来实现,
     但是我们总算有了新的方法,从我们熟悉的面向对象的方式来审视这门语言了。
     typescript对类的支持可谓是更加丰富,除了es6,es7已有的内容,还添加了一些术语。
    
        //面向对象的一些术语:
        1.类 Class:定义了一切事物的抽象特点,包含它的属性和方法。就像是一张蓝图,
        //比如汽车是一个class,就像是一张造汽车的图纸。
    
        2.对象 Object,类的实例,通过new生成,有了蓝图我们就可以创造实实在在的汽车。
        //我们可以说一辆奥利Q5是汽车类的实例,也可以说一辆奔驰是汽车类的另一个实例。
    
        3.面向对象OOP三大特征:封装 继承  多态。
        封装:(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。
              外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象。
    
        继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特征。
    
        多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。
    
        //比如猫和狗,他们都可以继承一次animal,但是他们分别实现了自己的eat,吃的方法,
        //此时针对某一个实例,我们无需了解它是猫或者狗,我们可以直接调用eat方法,
        //程序会自动判断出来应该如何执行某个方法。
    
    
    //面向对象编程给人一种做上帝的感觉。
    
    //举个例子:
    //创建了一个类,叫animal,它是一个基本类。
    class Animal {
      name: string;
      constructor(name: string) {  //里面有一个构造函数,构造函数是实例化执行的逻辑
        this.name = name          //一个方法
      }
      run() {
        return `${this.name} is running`
      }
    }
    const snake = new Animal('lily')
    console.log(snake.run())  //输出lily  is runing
    
    // 继承的特性
    class Dog extends Animal {  //extends继承以后,自然有了父类属性和方法
      bark() {                 //创建了一个新的方法
        return `${this.name} is barking`
      }
    }
    
    const xiaobao = new Dog('xiaobao')
    console.log(xiaobao.run())
    console.log(xiaobao.bark())
    
     //多态
    // 这里我们重写构造函数,注意在子类的构造函数中,必须使用 super 调用父类的方法,要不就会报错。
    class Cat extends Animal {
      constructor(name) {
        super(name)            //constructor这里进行了一个重写
        console.log(this.name) //多添加了一行
      }
      run() {
        return 'Meow, ' + super.run()  //run方法也进行了重写
      }
    }
    const maomao = new Cat('maomao')
    console.log(maomao.run())
    
    
     目前为止,我们都是讨论都是类的实例,实例上的属性和实例上的方法,
     那我们类上面有没有直接可以访问的属性和方法呢?
    
        //区别:不需要实例化,直接在类调用就可以
    
        class Cat extends Animal{
          static categories = ['mammal']  //创建了一个静态属性
          constructor(name){  
             super(name)
             console.log(this.name) 
           }
           run(){
             return 'Meow,'+super.run() 
           }
         }
    
        //console.log(Cat.categories())
    
        为什么要有静态属性或者方法呢?
        是因为这里面的定义和实例没太大关系,
    
        typeCsript怎么增强类?
        //三种访问修饰符,可以给类上的方法和属性提供权限管理,
        //有些内容是不愿意暴露给外部使用的
    
        public:修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是public的
        private:修饰的属性或方法是私有的,不能在声明它的类的外部访问
        protected:修饰的属性或方法是受保护的,它和private类似,区别是它在子类中也是允许被访问的
    
        //有些属性只能读不能写,
        //readonly修饰符号 
        class Animal{
           readonly name: string;
           constructor(name: string){
             this.name = name
           }
           run(){
             return `${this.name} is running`
           }
         }
    
        //const snake = new Animal('lily)
        //snake.name = '123' //会报错  Connot addign to 'name' because it is a read-only
    

    # 类与接口

    类实现一个接口

     //继承的困境
     //类可以使用implements来实现接口
    
    
        //之前学过接口Interface,用于对对象的形状shape进行描述,
        //我们还用它描述了函数的类型,
    
        //本节介绍接口的另一个用途:对类的一部分行为进行抽象
    
        //在面向对象的世界中一个类只能继承自另外一个类,
        //有时候不同类之间会有一些共同的特新,使用子类继承父类的方法,很难来完成。
        //这时候我们就可以把这些特性提取成接口,然后用一个称之为implements的关键字来实现。
        //这样就大大提高了面向对象的灵活性。
    
    //举个例子:
    //创建一个称之为car的类,他有一个特性是switchRadio,
    
        class Car{
           switchRadio(trigger: boolean){
           }
         }
    
    //现在又有一个蓝图出现了,负责创造一个手机类,手里类里面也有一个打开收音机的方法,
        class Cellphone{
          switchRadio(trigger: boolean){
           }
        }
    
        //我们发现这两个类有相同的特性,所以我们考虑把他们给提取出来,
        //如果用父类的形式,car和cellphone必须有一个合适的父类,
        //感觉很难找,
        //这是可以把这一个特性抽取成一个Interface,让这两个类都去实现它,
    
    
    interface Radio {  //里面有一个switchRadio方法
      switchRadio(trigger: boolean): void;  //void关键字代表什么都不返回
    }
    class Car implements Radio {
      switchRadio(trigger) {
      }
    }
    class Cellphone implements Radio {
      switchRadio() {
      }
    }
    //这时我们implements就发挥契约的作用,
    //告诉car和cellphone要去实现这个方法,
    //删掉这个方法的时候就会报错
    
    //通过Interface完成了逻辑功能的提取和验证,
    
    一个小功能:检查电池的容量,手机有,汽车没有
    //新创建一个接口
       interface Battery{
           checkBatteryStatus(): void;
       }
    
    // 要实现多个接口,我们只需要中间用 逗号 隔开即可。
    class Cellphone implements Radio, Battery {
      switchRadio() {
      }
      checkBatteryStatus() {
    
      }
    }
    
    接口之间还可以有继承的关系,注意这个是接口之间的继承,不是class之间的继承,
    但其实是和class之间的继承是一样的,
    新建一个接口
        interface RadioWithCellphone extends Radio{ //extends关键字继承
           checkBatteryStatus(): void
         }
        //RadioWithCellphone上边两个方法都有了,
    
        //可以替换上边的写法
        class Cellphone implements RadioWithCellphone{
           switchRadio(trigger){
           }
          checkBatteryStatus(){
          }
         }
    
      interface的一点点精髓:它仿佛是某种锲约可以定义和约束所有内容,
      比如object的样子可能用interface的方法来抽象类的属性和方法,
      还可以去定义一个函数类型,各种复杂的类型等等,
      所以这就是Duck typing的精髓,只要它走路像鸭子,叫起来像鸭子,
      不管你是什么东西,会用它来约束各种概念上毫不相关的内容。
    
      这节我们学会用interface和implements来抽象和验证类的属性和方法。
    

    相关文章

      网友评论

          本文标题:2020-10-30Typescript(1.2)

          本文链接:https://www.haomeiwen.com/subject/bqndvktx.html