共计 5591 个字符,预计需要花费 14 分钟才能阅读完成。
class
能够用来做数据的存储与回显,能将页面的数据分离出来并提取到 class
内,函数也能够抽离到 class
,实例化class
进行调用。ts
中的 class
类与 js
的class
类基本相同,不同点在于 ts
的class
有数据类型束缚,在应用 class
的时候,必须遵循定义的数据类型束缚,class
中有一个 constructor
,它能够更改class
的属性值,实例化 class
进行传值的时候,传入的值也必须合乎 constructor
参数的数据类型规定。
class 的应用
class Student {
// 定义属性
name : string = ''
age : number = 0
gender : string = ''
// 定义构造函数:为了未来实例化对象的时候,能够间接对属性的值进行初始化
constructor(name : string,age :number ,gender : string){
this.name = name
this.age = age
this.gender = gender
}
}
这里的定义属性是实例对象 class
本身的属性,而不是定义在对象原型上的,在实例化 class
的时候能够间接获取到 class
的属性,例如:let student = new Student
,取值:student .name
,此时取值必定是一个空,因为这个 name
并没有进行赋值,而是援用了默认值。
赋值操作
let {name,age,gender} = {name : '张三', age : 18, gender : "男"}
let student = new Student(name,age,gender)
console.log(student) // 打印 name : '张三', age : 18, gender : "男"
这里 new Student
就是实例化 class
, 并将值传入class
进行赋值操作,赋值操作是在 constructor
中实现的,通过 new
关键词实例化对象时,会主动调用 constructor
构造函数,ts
的 constructor
在接参的时候,须要定义参数的数据类型,这里传入了 name,age,gender
,那么在接参的时候,也必须定义这三个值,并且规定的数据类型必须统一。this.name = name
就是 class
的实例属性 =
传入的 name
参数,这一步就是赋值操作。赋值之后就能够在 let student
这个地位拿到数据。
间接 new class
,如果 不传值
或者传一个 null
则会应用 class
内的 默认值
,相当于是 重置 class
的值;如果 new 传入值
,那么就以 传入值为准
。
在应用 calss
时候的注意事项
1、class
的实例属性须要有默认值,如果没有初始化赋值则会报错
class PersonTest0 {
// 没有默认值 报错
name : string
}
class PersonTest1 {
name : string
constructor(info : any){
// 此处做了一个判断,并不是间接赋值,也会报错,去掉 if 间接 this.name = info.name 则不会报错
if(info){this.name = info.name}
}
}
// 定义了 constructor 然而没有初始化赋值,报错
class test2 {
name : string
constructor(name : string){// 没有 this.name = name 报错}
}
2、class
能够不必残缺传入定义的属性,传一部分也能够,未传入的以默认值或者 undefined
展现(ts
中须要定义传入类型,未传入的用 ?
可选符申明)。
interface IPersonTest {
name : string
age : number
address ?: string
}
class PersonTest {
name : string = ''
age : number = 0
address ?: string = ''
constructor(info : IPersonTest | null) {if(info){
this.name = info.name
this.age = info.age
this.address = info.address
}
}
}
let PInfo = {
name : 'zs',
age : 10,
// address : '湖北'
}
let getPerson = new PersonTest(PInfo) // 传入 constructor 值,给实例属性赋值
// 打印 zs , 10 , undefined
3、传入的程序并不影响对类的赋值
let PInfo = {
name : 'zs',
age : 10,
address : '湖北'
}
let PInfo2 = {
name : '东方不败',
age : 10,
address : '湖南'
}
let getPerson = new PersonTest(PInfo) // 传入 constructor 值,给实例属性赋值
console.log(getPerson);
console.log(new PersonTest(null)); // 传入 constructor 值为空则初始化实例属性的值
console.log(new PersonTest(PInfo2)); // 传入的程序并不影响对类的赋值,此处传入的是 PInfo2,失去的就是 PInfo2 的值
console.log(new PersonTest(PInfo)); // 传入的程序并不影响对类的赋值,此处传入的是 PInfo,失去的就是 PInfo 的值
class 内定义方法
class Student {
name : string
age : number
gender : string
constructor(name : string ,age :number ,gender : string){
this.name = name
this.age = age
this.gender = gender
}
// 定义实例办法
sayHi(say : string){console.log(`${say}你好, 我叫 ${this.name}, 往年曾经 ${this.age}岁了,我是个 ${this.gender}孩子 `);
}
}
let {name,age,gender} = {name : '张三', age : 18, gender : "男"}
let student = new Student(name,age,gender)
console.log(student.sayHi('你叫什么名字啊?'));
// 打印 你叫什么名字啊?你好, 我叫张三, 往年曾经 18 岁了,我是个男孩子
此处在 class
外部定义了一个办法,定义方法跟失常写函数是一样的,有参数且能够设置默认参数,参数必须的定义数据类型,class
的实例办法取值的话,用 this.xxx
就能够获取到 calss
内的属性值。class
的办法间接用 实例对象. 办法名 (student.sayHi())
即可。sayHi()
这个办法其实是间接定义在 Student.prototype
下面的,因而在类的实例上调用办法,其实是调用原型上的办法
默认值
class
的属性和办法都能够有默认值,如果实例化 class
没有传入参数则应用默认值
class cla {name : string = '属性默认值'}
let data = new cla () // new cla 间接获取到 name 的值
console.log(data) // 打印 属性默认值
class cla2 {
name : string
constructor(name : string = '东方不败') {this.name = name}
}
let data = new cla2() // new cla 后 constructor 的 name 赋值给 this.name
console.log(data.name); // 打印 东方不败
class cla3 {
name : string
constructor(name : string = '不败') {this.name = name}
sayHi(say : string = '西方'){console.log(`${say},${this.name}`);
}
}
let data = new cla3() // new cla 后, 函数获取 name 的值加上函数本身的默认值
console.log(data.sayHi()); // 打印 西方,不败
静态方法
class openInfo {fun(list) { // 实例办法
console.log(list)
}
static fun2(list) { // 静态方法
console.log(list)
}
}
let list1 = 50
new openInfo().fun(list1) // 打印 50
// class 的实例属性须要 new , 语法:类名(). 办法名()
let list2 = 100
openInfo.fun2(list2) // 打印 100
// class 的静态方法不须要 new,语法:类名. 办法()
类相当于实例的原型,所有在类中定义的办法,都不会被实例继承。如果在一个办法的后面加上 static
关键字,就示意该办法不会被实例继承,而是间接通过类来调用,这个就被称为静态方法。
动态属性
通常状况下,类的属性值两种,第一种实例属性,第二种动态属性
第一种: 实例属性 & 实例对象原型
- 实例属性就是定义在类
constructor
下面,最顶层的地位,不须要this
,跟类外部的函数是平级的,这种形式定义的是实例对象本身的属性 - 而在
constructor
内定义的this.xxx
则为实例对象的原型属性。class
能够不必残缺传入定义的属性,传一部分也能够,未传入的以默认值或者undefined
展现(ts
中须要定义传入类型,未传入的用?
可选符申明)。 - 这两个办法并没有什么实质的区别,实例属性上定义的能够有默认值。
第二种:动态属性 & 静态方法
-
在实例属性或者实例办法的后面加一个
static
,则为动态属性,动态属性不须要new
,取值办法:类名. 属性名 即可实例属性是须要 new 的,例如 new Person() 或者 new Person(). 办法名() 或者 new Person(). 属性名
动态属性则间接 类名. 属性名,例如:Person. 办法名() 或者 Person. 属性名
class PersonStatic {
// name 在动态属性中是一个关键字,不容许应用
//static names : string // 此处不赋值就是一个 undefined
static names : string = ''
static age : number = 0
static address : string = ''
static obj : any = {
user : '南瓜粥',
money : 5
}
static sayHi(){} // 静态方法
}
console.log(new PersonStatic); // 打印 PersonStatic 类
console.log(PersonStatic.names,PersonStatic.age,PersonStatic.address); // 获取初始化的值,空则不显示
console.log(PersonStatic.names = '西方求败',PersonStatic.age = 10,PersonStatic.address = '湖北'); // 动态属性改值
console.log(PersonStatic.names = '艺术概论'); // 动态属性改值
console.log(PersonStatic.obj = {user:'紫薯粥',money:6}); // 对象改值
// console.log(PersonStatic = 100); // 报错
打印后果:
动态属性能够间接改值,改值的程序并不影响它的输入,它与实例属性不同的是,实例属性定义的是实例对象本身的属性, 是在 class
身上的。
constructor
能够更改实例属性的值,动态属性
和办法
则是间接定义在构造函数 constructor
中的,所以能够间接改值。而且此处也解释了为什么在动态属性中 name
无奈应用,因为 name
被类本身占用了。
- 不同点
class
实例属性能够通过构造函数constructor
传入的值来批量的改值- 动态属性必须单条的 类名. 属性名 改值
接口
1、接口能够束缚 class
外部值的数据类型以及办法,class
应用接口之后,接口定义的数据类型和办法必须全副真正实现,并且在实现的根底上,class
能够有本人的属性和办法。接口内能够定义属性和办法,这里以办法为例子。
// 接口
interface IFly{fly() : string // 办法 返回字符串类型
}
class Person implements IFly {fly() : string {// 实现接口中的办法,class 没有 fly()会报错
return '我会飞了'
}
run() : string { // calss 本身定义的办法
return '我会跑了'
}
}
Person
类里必须得有 IFly
定义的 fly()
,而且办法得有字符串返回值,否则报错。
2、class
类能够实现一个接口也能够实现多个接口,接口中的内容都要真正实现
// IMy 继承下面定义的两个接口
interface IRun{run() : string // 办法 返回字符串类型
}
interface IFly{fly() : string // 办法 返回字符串类型
}
// 类能够实现一个接口也能够实现多个接口,接口中的内容都要真正实现
class Person2 implements IFly,IRun {fly() : string {return '我会飞了'}
run() : string {return '我会跑了'}
}
let person2 = new Person2()
console.log(person2.fly(),person2.run());
接口是能够继承的,class
能够应用继承的接口,也能够应用多个接口,办法是一样的,对于接口继承,请看另外一篇:【TS】接口和接口继承
案例源码:https://gitee.com/wang_fan_w/ts-seminar
如果感觉这篇文章对你有帮忙,欢送点亮一下 star