引入
首先我们来看一段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去间接的修改。提高安全性。