ts 类初探
当大家看到typescript(ts) 中的类(class)时候,可能好多人都会想起面向对象,对的,面向对象是许多后台的一种编程思想,比如: 本人曾经接触的java, 里面就是用的是面向对象的思想。但是本文不讨论面向对象,值讨论ts 中 class 新增的语法,和一些使用方法以及注意事项。
回顾es6中的类
// 定义一个用户的类,里面有两个属性,名字和年龄 class User { constructor(name, age) { this.sex = "男"; this.id = Math.random().toString(32).substr(-6); this.name = name; this.age = age; } getAge() { return this.age; } /** * 静态方法,不能被实例化,就是说不可以通过new User().getNumber(), 这样调用时会报错的 * 调用的方式,可以使用 User.getNUmber(), 或者通过继承的方式进行调用 */ static getNumber() { return '1'; } } const u = new User(123, 12); console.log(u.getAge()); 123 console.log(User.getNumber()); 1
问自己一个问题,上面的这种形式有没有存在些问题?
- 缺少类型检查,上面user 里面的name 和 age 我们可以随便的传值。可能有的人会说,我们可以用set和get来进行限制。对的,如果能想到这个,确实学习的不错。但是考虑过一个问题吗? 我定义的一个类中,除了构造函数外(假设有100个需要类型检查的属性值),那里面岂不是全是get 和 set, 那这个和 java等后端的语言有啥区别?(这里不是对语言有偏见哈)
- 哪些属性是Class 私有的,只读的,哪些是公开的呢? 有的同学说我们可以使用 es6 里面的 symbol(符号)来定义私有的,对的,但是个人感觉会有点小麻烦。🤭
- 代码提示不是很友好(vscode有代码提示,往往都要开发者记忆类里面的关键词)等
解决办法: ts 主角上场(ts 是静态的可以的类型检查系统,是没有说完全需要使用这个的哈) 传送门
先看ts如何来解决上面的哪些问题:
// require('./poker/index.ts') class User { // 在这里声明类的属性列表 readonly id: string // 定义只读属性 name: string; age?: number; // 定义可选属性 sex: "男" | "女" = "男" // 初始化赋值 constructor(name: string, age: number) { this.id = Math.random().toString(32).substr(-6); this.name = name; this.age = age; } /** * 定义私有的函数 */ private getAge() { return this.age; } }
注意: 上面的代码,在代码的书写上,是比原来的es6的代码增多了。但是需要类型检查等功能,是会增加一层额外的代码。
编译结果分析:
ts Class 基本知识点
属性
使用属性列表来描述类中的属性:
例如上面的:
属性的初始化检查
这个是检查,哪些属性可以有默认值,比如上面的sex,我们定义的类型是一个 类型别名,sex 那么是男,要么是女,我们完全可以使用默认值的,需要开启这个功能,在 tsconfig.json 中添加一个配置 strictPropertyInitialization:true
属性初始化的位置
1.在构造函数中,可以初始化属性的值
2.给属性付给默认值
在属性列表中,直接给属性付给默认值,这样也可以ok的。
属性修饰符
- readonly: 只读的,写在属性,方法等的前面,标记改属性是只读,如果后序代码修改的化,ts 会给出类型检查报错
- public:公共的,写在属性,方法等的前面,但是这个修饰符一般可以不写,因为ts默认的都是所有的属性是公开的
- private: 私有的,写在属性,方法等的前面。标记改属性或者方法只能在类中使用,在其他地方使用,也会报错
- protected: 受保护的,书写的方式也是同样的,标记改属性或者方法是受保护的。在类里面、子类里面可以访问 ,在类外部没法访问。
属性简写
如果某个属性,通过构造函数的参数传递,并且不做任何处理的赋值给该属性。可以进行简写, 例如:
// 假设有一个类就是这样的 class User { name: string age: number constructor(name: string, age: number) { this.name = name; this.age = age; } }
可以简写
class User { constructor(public name: string, public age: number) { } }
效果:
访问器
作用:用于控制属性的读取和赋值
也有两种方式: 一种是类似Java的形式,另一种是es 里面更新的
- java 形式的
// class User { name: string age: number constructor(name: string, age: number) { this.name = name; this.age = age; } setName(value: string) { // 这里可以对名字做业务处理 this.name = value; } getName() { return this.name; } } const u = new User('cll', 12); u.name = 'cll123'; // 设置值 console.log(u.name) // 获取值
效果:
- es7形式的
// require('./poker/index.ts') // 假设有一个类就是这样对的 class User { _name: string age: number constructor(name: string, age: number) { this._name = name; this.age = age; } set name(value: string) { // 这里可以对名字做业务处理 this._name = value; } get name() { return this._name; } } const u = new User('cll', 12); u.name = 'cll123'; console.log(u.name)
效果: