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.nameconsole.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 = 50new openInfo().fun(list1) // 打印50// class的实例属性须要new ,语法:类名().办法名()let list2 = 100openInfo.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