TS-属性的封装

350 阅读3分钟

引入

首先我们来看一段ts简单的代码,定义了一个表示人的类,其中有name和age属性,下面可以在声明了实例对象后,接着通过实例对象,对属性值进行修改,可是正是因为现在的属性是直接在对象中设置的,可以被任意的修改,所以这样是很不安全的!比如我想直接把年龄改成负数,也是可以直接修改的,但是年龄不可能是负数啊,明显存在问题,于是就有了接下来介绍的TS的属性修饰符们。

(function(){
  // 定义一个表示人的类
  class Person{
    _name:string;
    _age:number;

    constructor (name:string,age:number){
        this.name=name;
        this.age=age;
    }
  }

  const per=new Person('zs',18)

  per._name='ls';
  per._age=20;
  console.log(per);
})()

TS属性的修饰符

  • public 修饰的属性可以在任意位置进行访问(修改),public也是默认值,如果不在属性前定义修饰符默认的话就是public
(function(){
  // 定义一个表示人的类
  class Person{
    public _name:string;
    public _age:number;

    constructor (name:string,age:number){
        this.name=name;
        this.age=age;
    }
  }

  const per=new Person('zs',18)

  per._name='ls';
  per._age=20;
  console.log(per);
})()
  • protected是受包含的属性,只能在当前的类与子类中调用

同如下代码,虽然num属性是在A里面,但是因为B继承了A的属性,所以num属性在B里面也同样可以访问,但num属性就不可以通过实例去访问哦,这是protected,只能在类里面访问,这点就和下面介绍的private私有属性是一样的了。

class A{
    protected num :number;
    constructor(num:number){
      this.num=num;
    }
  }

  class B extends A {
    test (){
      console.log(this.num);
    }
  }

  const b=new B(123)
  • private私有属性,只能在类内部进行访问(修改)

如下面的代码,在name和age属性前面添加了private,这两个属性变成了私有属性,constructor是在类的内部,于是便可以访问,name和age这两个私有属性,但在类的外部想通过实例对象直接修改这两个私有属性,便会报错。通过private提高了安全性,使得属性值不能任意修改。

(function(){
  // 定义一个表示人的类
  class Person{
    private _name:string;
    private _age:number;

    constructor (name:string,age:number){
        this.name=name;
        this.age=age;
    }
  }

  const per=new Person('zs',18)

  // per.name='ls';
  // per.age=20;
  console.log(per);
})()

注意:因为这些属性是在ts中独有的,在js中会被直接忽略,所以依旧是可以通过编译,修改属性值成功的,解决方法,就是在tsconfig.json文件中,添加一个配置文件,"noEmitOnError": true,就可以阻止错误的编译了。

接下来又存在新问题,如果直接这样定义的话,这些类里面的属性只能在类里面调用,如果外面实在需要调用怎么办呢?答案是可以通过在类里面暴露几个方法,供类外面使用,间接的可以的得到类里面的属性,接下来就来浅浅介绍一下属性的存取器吧!

属性的存取器

  • getter方法用来读取属性
  • setter方法用来修改属性

它们被称为属性的存取器,通过getter和setter可以获取和修改类里面的属性,接着从外部调用这些方法,便可以实现了,可以在存取器中设一些获取和修改的限制条件,也达到了不可任意修改的目的,提高代码的安全性!

如下代码,在set age中添加一个if判断条件,从而使得不能将age的值修改为小于0,解决了文章开头的问题。这样就不能将age修改成小于0的值了。

(function(){
  // 定义一个表示人的类
  class Person{
    private _name:string;
    private _age:number;

    constructor (_name:string,_age:number){
        this._name=name;
        this._age=age;
    }

    get name(){
      return this._name
    }
    set age(value:number){
      if(value>=0){
        this._age=value
      }
    }
  }

  const per=new Person('zs',18)
  
  //这里的age是调用上面的方法哦
  per.age=20;
  console.log(per);
})()

总结

属性的封装其实就是让我们的代码变得更加安全可靠,不会直接的去访问修改,而是通过getter,setter去间接的修改。提高安全性。