前言
原因:为了实现继承的方式不显得冗长和混乱,es6引入了class关键字。
原理:原型和构造函数的概念。
定义方式
- 🥱类声明式:
class Person {}
- 🥱类表达式:
Person = class {}
数据类型
typeof Person //function
与函数的区别
- 🥱类受块作用域的限制,函数受函数作用域
- 🥱类没有声明提升
🥱类的构造函数: new对象时候,执行的步骤。
(1) 在内存中创建一个新对象。
(2) 这个新对象内部的[[Prototype]]指针被赋值为构造函数的 prototype 属性。
(3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。
(4) 执行构造函数内部的代码(给新对象添加属性)。
(5) 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
实例成员 与原型
每个实例都对应一个唯一的成员对象,这意味着所有成员都不会在原型上共享。
class Person {
constructor(){
// 添加到 this 的所有内容都会存在于不同的实例上
this.name = new String('ll')
}
//添加到🥱的原型上
locate(){}
}
const p1 = new Person();
const p2 = new Person();
console.log(p1.name === p2.name) //false
//调用🥱类方法
p1.locate()
p2.locate()
static 关键字
class Person {
static title = 'static title'
constructor(){
this.title = 'constructor title'
}
//定义在🥱类本身上
static sayname(){
console.log(this.title)
}
//定义在原型上
sayname(){
console.log(this.title)
}
}
//调用方式
Person.sayname() // static title
new Person().sayname() // constructor title
继承
class Person1 extends Person{}
Person1.sayname() // static title
Person1.title = 'Person title'
Person1.sayname() // Person title
私有属性
class Person{
//签名加一个 #
#title = 'this is 私有 title'
sayTitle(){
console.log(this.#title)
}
}
const p = new Person()
p.sayTitle() // this is 私有 title
console.log(p.#title) //报错
迭代器
class Person {
constructor() {
this.nicknames = ['Jack', 'Jake', 'J-Dog'];
}
// 若不写这个,则返回constructor里面的属性,和类本身非static的属性
[Symbol.iterator]() {
return this.nicknames.entries();
}
}
let p = new Person();
for (let [idx, nickname] of p) {
console.log(nickname);
}
// Jack
// Jake
// J-Dog
super
1. 只能在派生类里使用
class Person {
static sayName(){
console.log('Person static sayName')
}
sayName(){
console.log('Person new sayName')
}
}
class Person1 extends Person{
// 在🥱类构造函数里使用
constructor(name){
super(name)//只能这样使用, 并且才能使用this,否则会报错
this.name = name
}
//在静态方法里使用
static sayName(){
super.sayName()
}
//实例方法使用
sayName(){
super.sayName()
}
}
Person1.sayName() // Person static sayName
const p = new Person1()
p.sayName() // Person new sayName
!!!!
1. 不能console.log(super)
2. 在constructor super()执行之后,才能使用this
3. 只能super.[方法],super.[属性]为undefined
4. 只能在派生类使用
TS 中的类🥱
公共(public),私有(private)与受保护(protected)的修饰符
这三个修饰符只能在ts文件里使用,默认的为public
class Person{
// 不能被继承,只能在Person里使用,不能被实例化
private name1 = 'private name'
// 可被继承,不能被实例化
protected name2 = 'protected name'
sayName1(){
console.log(this.name1) //private name
}
sayName2(){
console.log(this.name2) //protected name
}
}
class Person1 extends Person {
sayName1(){
console.log(this.name1) // error 报错 Property 'name1' is private and only accessible within class 'Person'.
}
sayName2(){
console.log(this.name2)//protected name
}
}
const p = new Person1()
p.name1 //error
Readonly
只能读取 不能设置
class Person{
readonly name = 'aaa'
constructor(){
this.name = 'll' //error
}
}
抽象类 abstract
抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。
abstract class Person{
abstract sayName():viod;//必须在派生类实现
}