ts 类初探
当大家看到typescript(ts) 中的类(class)时候,可能好多人都会想起面向对象,对的,面向对象是许多后台的一种编程思想,比如: 本人曾经接触的java, 里面就是用的是面向对象的思想。但是本文不讨论面向对象,值讨论ts 中 class 新增的语法,和一些使用方法以及注意事项。
回顾es6中的类
// 定义一个用户的类,里面有两个属性,名字和年龄
class User {
constructor(name, age) {
this.sex = "男";
this.id = Math.random().toString(32).substr(-6);
= 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);
= name;
this.age = age;
}
/**
* 定义私有的函数
*/
private getAge() {
return this.age;
}
}
注意: 上面的代码,在代码的书写上,是比原来的es6的代码增多了。但是需要类型检查等功能,是会增加一层额外的代码。
编译结果分析:
ts Class 基本知识点
属性
使用属性列表来描述类中的属性:
例如上面的:
属性的初始化检查
这个是检查,哪些属性可以有默认值,比如上面的sex
,我们定义的类型是一个 类型别名,sex 那么是男,要么是女,我们完全可以使用默认值的,需要开启这个功能,在 tsconfig.json
中添加一个配置 strictPropertyInitialization:true
属性初始化的位置
- 在构造函数中,可以初始化属性的值
- 给属性付给默认值
在属性列表中,直接给属性付给默认值,这样也可以ok的。
属性修饰符
readonly
: 只读的,写在属性,方法等的前面,标记改属性是只读,如果后序代码修改的化,ts 会给出类型检查报错-
public
:公共的,写在属性,方法等的前面,但是这个修饰符一般可以不写,因为ts默认的都是所有的属性是公开的 private
: 私有的,写在属性,方法等的前面。标记改属性或者方法只能在类中使用,在其他地方使用,也会报错protected
: 受保护的,书写的方式也是同样的,标记改属性或者方法是受保护的。在类里面、子类里面可以访问 ,在类外部没法访问。
属性简写
如果某个属性,通过构造函数的参数传递
,并且不做任何
处理的赋值给该属性。可以进行简写, 例如:
// 假设有一个类就是这样的
class User {
name: string
age: number
constructor(name: string, age: number) {
= 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) {
= name;
this.age = age;
}
setName(value: string) {
// 这里可以对名字做业务处理
= value;
}
getName() {
return ;
}
}
const u = new User('cll', 12);
= 'cll123'; // 设置值
console.log() // 获取值
效果:
- 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);
= 'cll123';
console.log()
效果: