• TS学习(八) :TS中的类


    TS中类的书写

    以前在js中书写类是这样的,然后我们在加上TS的类型检查你会发现报错了

    1. class User {
    2. constructor(name:string,age:number) {
    3. this.name=name;
    4. this.age=age;
    5. }
    6. }

    为什么呢? 在TS中他认为你这样写代码不是很好,因为在TS中你把User这个类写出来以后,

    它里面有哪些属性和方法,你应该很清楚的知道,所以TS认为你这些属性应该单独在一个地方写,

    而不是使用构造函数constructor动态的创造数据,在js中是可以使用构造函数取动态添加数据,

    而在TS中是不允许的,TS认为在创建一个对象后是不允许取给对象添加属性的,

    由于动态添加属性,可能会存在一些隐患,所以TS是不允许我们动态添加属性的

    1. const obj = {}
    2. obj.name='蜗牛';
    3. obj.age=18;

    知识补充

    在TS中这样是不行的,有人可能就会说因为const原因,我只能说小伙子你还年轻,js基础不扎实,

    const 我一般是用来定义常量的,就是一些固定的东西比如某个状态码,如 const STATUS=200,

    像这样的 放在配置文件中,使用时候导入进行使用,const 说定义的值不能改变,说的其实就是内存地址

    基本数据类型内存地址是不会变的,而引用数据类型,内存地址是会改变的,这里为什么还是可以使用const

    那是因为const 不能改变的只是引用数据类型的名字,地址是可以换的,比如 const 房间1={},定义一个房间

    名字叫”房间1“,虽然我可以给房间里面添加删除东西,但是房间名字没有改变,那我是不是可以吧另外一个房间的名字也改成”房间1“,

    只不过地址换了,但是名字没有变,所以就是这个道理


    知识点补充完,继续TS,既然TS不允许动态添加属性那该怎么书写呢

    使用属性列表来描述类中的属性,什么意思,举个🌰

    1. class User {
    2. name:string
    3. age:number
    4. constructor(name: string, age: number) {
    5. this.name=name;
    6. this.age=age;
    7. }
    8. }
    9. const u= new User("蜗牛",18);
    10. //不能添加属性
    11. u.sex="男"//这里就会报错
    12. //还可以这样赋值
    13. const u= new User();
    14. u.name="蜗牛",18
    15. u.age=18

    把属性写在类里面,表示这个类里面有这些属性,在后面使用时只能使用这些属性,不能添加,否则会报错

    在这里我想到这个好像有点难受,万一我的属性有很多,那不是要写一堆,感觉好麻烦

    属性的初始化检查

    有时候我们可能忘记了给对象赋值,如:在构造函数中没有给age赋值

    1. class User {
    2. name:string
    3. age:number
    4. constructor(name: string, age: number) {
    5. this.name=name;
    6. }
    7. }
    8. const u= new User("蜗牛",18);

    但是他不会报错,但是有些属性我们必须要赋值的,那这个时候怎么办呢

    这里我们就得用到一个配置了 strictPropertyInitialization,更加严格的检查属性有没有初始化,会检查属性有没有赋值

    1. {
    2. "compilerOptions": {
    3. "target": "es2016",//配置编译目标代码的版本标准
    4. "module": "commonjs",//配置编译目标使用的模块化标准
    5. "lib": ["es2016"], //表示默认详情下ts使用的是那一个环境
    6. "outDir": "./dist",//编译结果的目录
    7. "strictNullChecks": true,//TS检查变量是否是null
    8. "removeComments": true,/*编译结果中是否包含注释*/
    9. "noImplicitUseStrict": true,/*编译结果中是否有"use strict"*/
    10. "esModuleInterop": true,//启用es模块化交互非es模块导出
    11. "strictPropertyInitialization": true,//更加严格的检查属性有没有初始化
    12. },
    13. "include":["./src"],//执行ts的目录
    14. }

    加上这个配置后,上面构造函数中没有给age赋值,TS就会提示age属性报错,我们必须给属性进行赋值

    属性默认值

    当然我们也可以给属性进行默认值,比如默认性别为”男“,做法有两种

    • 方法1,构造函数参数默认法,这样在创建user对象时可以不传就是默认的男,如果想要修改,则const u= new User("蜗牛",18,"女"),这样就可以了

      1. class User {
      2. name:string
      3. age:number
      4. gender: "男" | "女"
      5. constructor(name: string, age: number,gender:"男" | "女" = "男") {
      6. this.name=name;
      7. this.age=age;
      8. this.gender=gender;
      9. }
      10. }
    • 方法2,属性默认法,在定义属性时就给默认值,在定义属性gender时,就给默认值为男,这样在构造函数里面就不用给这个属性进行赋值,

      那这里有个问题,既然构造函数里面没有该属性的赋值操作,那该怎么修改该属性呢,如果你想要在const u= new User("蜗牛",18,"女")这里面加一个参数,你会发现没有用,

      因为构造函数都没有该参数,加了也没有,正确的方法时,使用 对象[属性]="XX"; 的方式进行修改,如 u.gender="女";这样就可以改变值了

      1. class User {
      2. name:string
      3. age:number
      4. gender: "男" | "女" = "男"
      5. constructor(name: string, age: number) {
      6. this.name=name;
      7. this.age=age;
      8. }
      9. }

    属性可选值

    当属型是可以有值也可以不传时,如当我们的身份证号可以填写也可以不填时,该怎么给属性赋值呢,两种方法

    • 方法1、 “|”符号 IDCard:string | undefined = undefined,这样的写法

      1. class User {
      2. IDCard: string | undefined =undefined;
      3. constructor() {
      4. }
      5. }
    • 方法2、链式操作法 IDCard?: string,像js中的链式操作一样

      1. class User {
      2. IDCard?: string
      3. constructor() {
      4. }
      5. }

    只读属性

    当某个属性创建后就无法更改时,那这个属性后面就不能在进行修改了,那我们就得用到readonly,加上这个后,在后面就无法进行修改了

    1. class User {
    2. readonly uid:number
    3. constructor() {
    4. this.uid=new Date().getTime()
    5. }
    6. }
    7. const u= new User();
    8. //这里想修改,结果不让修改,报错
    9. u.uid=1

    访问修饰符,可以控制类中的某个成员的访问权限

    • public:默认的访问修饰符,公开的,所有的代码均可访问

    • private: 私有的修饰符,只有在类中可以访问

      1. class User {
      2. readonly uid:number
      3. name:string
      4. age:number
      5. gender: "男" | "女" ="男"
      6. IDCard?: string
      7. private money:number = 1000000//这是自己的钱,不希望外面进行访问,进行修改
      8. useMoney: number =0//使用钱和赚到的钱
      9. constructor(name: string, age: number) {
      10. this.uid=new Date().getTime()
      11. this.name=name;
      12. this.age=age;
      13. }
      14. makeMoney(){
      15. this.money +=this.useMoney
      16. console.log("剩余金额"+this.money)
      17. }
      18. }
      19. const u= new User("蜗牛",18);
      20. u.useMoney=1000//挣钱
      21. u.makeMoney()//查看还有多少钱

      补充:在js中要实现私有的可以使用Symble;当然这些修饰符也可以用在方法上,这样私有方法外部禁止调用

      1. class User {
      2. private money:number = 1000000//这是自己的钱,不希望外面进行访问,进行修改
      3. useMoney: number =0//使用钱和赚到的钱
      4. constructor() {
      5. }
      6. private makeMoney(){
      7. this.money +=this.useMoney
      8. console.log("剩余金额"+this.money)
      9. }
      10. }
      11. const u= new User();
      12. u.makeMoney()//这里就会报错,禁止调用该方法

    补充

    我们这样写,构造函数里面直接赋值给属性,没有做任何操作,这样显得太机械化,麻烦,

    1. class User {
    2. name:string
    3. age:number
    4. constructor(name: string, age: number) {
    5. this.name=name;
    6. this.age=age;
    7. }
    8. }

    TS给了我们一个语法糖, 当一个属性在构造函数里面,没有做任何操作就直接赋值给属性了,可以简写成,如下,这样和上面的写法得到的结果是一样的

    这样的写法 有且仅当,属性通过构造函数的参数传递,并且不做任何处理的赋值给该属性,可以进行简写

    1. class User2 {
    2. constructor(public name: string,public age: number) {}
    3. }
    4. const u2=new User2("可莉",18)
    5. console.log(u2);
  • 相关阅读:
    昇思MindSpore安装教程
    字符串匹配算法(C/Java实现)
    python---网络编程
    打开word文档报错,提示HRESULT 0x80004005 位置: 部分: /word/comments.xml,行: 0,列: 0
    登录测试用例
    猿创征文|手把手玩转docker,从入门到精通
    第八章 :如何基于Spring Boot +Mybatis 快速开发 Restful API
    Zookeeper分布式一致性协议ZAB源码剖析
    深圳市福田区支持文化创意产业发展若干措施
    vue中,使用file-saver导出文件,下载Excel文件、下载图片、下载文本
  • 原文地址:https://blog.csdn.net/weixin_41277748/article/details/125902230