1、 类定义
类声明 class Person {}
类表达式 const Animal = class {};
2、 类的实例化
1、使用 new 调用类的构造函数会执行如下操作。
(1) 在内存中创建一个新对象。
(2) 这个新对象内部的[[Prototype]]指针被赋值为构造函数的 prototype 属性。
(3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。
(4) 执行构造函数内部的代码(给新对象添加属性)。
(5) 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
class Person {
city: string;
constructor() {
console.log("xxx");
this.city = "昆明";
}
}
2、 类实例化时传入的参数会用作构造函数的参数
class Person {
city?: string;
constructor(city?: string) {
console.log(arguments.length);
this.city = city;
}
}
let p1 = new Person("昆明"); // 1
console.log(p1.city); // 昆明
3、 每个实例都对应一个唯一的成员对象,这意味着所有成员都不会在原型上共享
class Person {
name: String;
constructor() {
this.name = new String("pengze");
}
}
let p1 = new Person();
let p2 = new Person();
console.log(p1.name); //pengze
console.log(p2.name); //pengze
p1.name = "pp1";
p2.name = "bb2";
console.log(p1.name); //pp1
console.log(p2.name); //bb2
4、添加到this上的所有内容,都会存在不同的实例上, 在类块中定义的所有内容都会定义在类的原型上, 通过static关键字作为前缀 定义在类本身上
class Person {
name = "Jake";
constructor() {
this.name = "pengze";
}
setName() {
console.log(`我在原型上`);
}
static getName() {
console.log(`静态方法存在类的本身上`)
}
}
let p = new Person();
console.log(p.name); //pengze
console.log(Person.prototype.setName()); //我在原型上
console.log(Person.getName()) // 静态方法存在类的本身上
3、 类的继承
1、ES6 类支持单继承。使用 extends 关键字,就可以继承任何拥有[[Construct]]和原型的对象。很大程度上,这意味着不仅可以继承一个类,也可以继承普通的构造函数
class Vehicle {}
// 继承类
class Bus extends Vehicle {}
let b = new Bus();
console.log(b instanceof Bus); // true
console.log(b instanceof Vehicle); // true
function Person() {}
// 继承普通构造函数
class Engineer extends Person {}
let e = new Engineer();
console.log(e instanceof Engineer); // true
console.log(e instanceof Person); // true
2、 supur的使用
(1.1) 不要在调用 super()之前引用 this,否则会抛出 ReferenceError
(1.2) super 只能在派生类构造函数和静态方法中使用
(1.3) 不能单独引用 super 关键字,要么用它调用构造函数,要么用它引用静态方法
(1.4) 调用 super()会调用父类构造函数,并将返回的实例赋值给 this
class Vehicle {
name: boolean;
constructor() {
this.nameBoolean = true;
}
}
class Bus extends Vehicle {
constructor() {
super(); // 相当于 super.constructor()
console.log(this instanceof Vehicle); // true
console.log(this); // Bus { nameBoolean: true }
}
}
new Bus();
(1.5) 如果没有定义类构造函数,在实例化派生类时会调用 super(),而且会传入所有传给派生类的参数。
class Vehicle {
brand!: string;
constructor(brand: string) {
this.brand = brand;
}
}
class Bus extends Vehicle {}
console.log(new Bus("劳斯莱斯")); // Bus { brand: '劳斯莱斯' }
(1.6) 如果在派生类中显式定义了构造函数,则要么必须在其中调用 super(),要么必须在其中返回一个对象。
class Vehicle {}
class Car extends Vehicle {}
class Bus extends Vehicle {
constructor() {
super();
}
}
class Van extends Vehicle {
constructor() {
// super();
return {};
}
}
console.log(new Car()); // Car {}
console.log(new Bus()); // Bus {}
console.log(new Van()); // {}