一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
类(Class)是面向对象程序设计(OOP,Object-Oriented Programming)实现信息封装的基础。类是一种用户定义的引用数据类型,也称类类型。每个类包含数据说明和一组操作数据或传递消息的函数。类的实例称为对象。(百度百科)
ES6中的类写法
举个栗子
class User {
constructor(name, age) {
this.name = name
this.age = age
}
}
这个写法在 js 最正常不过了, 但是在 ts 这种写法是不正确的。
ts 认为this.name = name; this.age = age 这种动态增加属性是不太合理的, 因为在创建这个 User 时, 应该很清楚User需要的属性应该是提前确定的然后才可以动态增加。
TS中的类写法
类 需要什么属性应该使用 属性列表 来描述类中的属性。
举个栗子
class User {
//===== S 属性列表 =====
name: string
age: number
//===== E 属性列表 =====
constructor(name, age) {
this.name = name
this.age = age
}
}
注意点: 有时候可能定义了 属性列表 但是忘记书写 构造函数 部分
class User {
//===== S 属性列表 =====
name: string
age: number
//===== E 属性列表 =====
}
这里的 User 的 name、age 的默认值为 undefined, 但是我明确的告诉它为 string、number所以我希望 ts 在这种情况下提示我写法错误, 可以在 tsconfig.json 添加配置:compilerOptions.strictPropertyInitialization : true 使用更加严格的方式来检查属性的初始化。
加上配置后, ts 就会提示 User 忘记了属性的初始化。
属性初始化
属性的初始化可以在 constructor 中完成, 也可以在 属性列表 中完成。
假如 User 有一个 sex 属性的默认为 男, 就可以这样写
class User {
//===== S 属性列表 =====
name: string
age: number
sex: '男' | '女' = '男'
//===== E 属性列表 =====
constructor(name, age) {
this.name = name
this.age = age
}
}
当在 属性列表 列表中初始化之后, 就可以不用在 constructor 初始化了, 当然也可以在 constructor 初始化
class User {
//===== S 属性列表 =====
name: string
age: number
sex: '男' | '女'
//===== E 属性列表 =====
constructor(name, age, sex:'男' | '女' = '男') {
this.name = name
this.age = age
}
}
使用 js 的参数默认值也能搞定。
访问器(ES6中的语法)
控制属性的读取和赋值
开发中有一种场景, 就是对用户的年龄赋值, 但是对年龄有几种要求, 不能是负数、小数、大于200, 那么就需要对 年龄属性进行精密的控制, 这是就能使用到访问器。
我们可能会这样书写代码
class User {
constructor(public name: string, private _age: number = 18) {
this.name = name
this._age = _age
}
//获取年龄
getAge(): number {
return Math.ceil(this._age)
}
//设置年龄
setAge(value: number): void {
//在这里可以对val做一些处理
if (value < 0) {
this._age = 0
} else if (value >= 200) {
this._age = 200
} else {
this._age = value
}
}
}
const u: User = new User('zhangsan')
u.setAge(20)
u.getAge() //20
通过函数的方式来控制内部的私有属性
这种写法完全没有问题, 但是在使用的时候感觉上获取年龄是调用一个函数, 可能会觉得有点别扭, 为了达到使用上直接给属性赋值的写法就可以使用 访问器 改造一下。
class User {
constructor(public name: string, private _age: number = 18) {
this.name = name
this._age = _age
}
//获取年龄
get age(): number {
return Math.ceil(this._age)
}
//设置年龄
set age(value: number) {
//在这里可以对val做一些处理
if (value < 0) {
this._age = 0
} else if (value >= 200) {
this._age = 200
} else {
this._age = value
}
}
}
const u: User = new User('zhangsan')
u.age = 20 //在赋值感觉上 是给一个属性赋值
u.age //20
体现在使用上的方便快捷
还可以把上面的 set 函数删除, 这样 age 就是一个可读的属性了(本质是执行函数)。
总结
TS 中的类更像后端语言的写法, 搭配上访问修饰符,让类的书写更加有条理。