Es6 类
1. 类的定义
js
class Person {
}
console.log(typeof Person) // function
var p = new Person()
console.log(p.__proto__ === Person.prototype) // true
2. 类中的方法定义
- 属性
- 实例方法
- 访问器方法
- 静态方法
js
var names = ["abc", "cds", "qew"];
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
this._address = "广州市";
}
// 普通的实例方法
// 创建出来的对象进行访问
// var p = new Person()
// p.eating()
eating() {
console.log(this.name + " eating~");
}
running() {
console.log(this.name + " running~");
}
// 类的访问器方法
get address() {
console.log("拦截访问操作");
return this._address;
}
set address(newAddress) {
console.log("拦截设置操作");
this._address = newAddress;
}
// 类的静态方法(类方法)
// Person.createPerson()
static randomPerson() {
var nameIndex = Math.floor(Math.random() * names.length);
var name = names[nameIndex];
var age = Math.floor(Math.random() * 100);
return new Person(name, age);
}
}
var p = new Person("hzy", 18);
p.eating();
p.running();
console.log(p.address);
p.address = "北京市";
console.log(p.address);
// console.log(Object.getOwnPropertyDescriptors(Person.prototype))
for (var i = 0; i < 50; i++) {
console.log(Person.randomPerson());
}
3. 类的继承
- super调用
- 子类重写父类的方法
- 子类调用super并重写父类的方法
- 子类重写父类的静态方法
- 子类调用super并重写父类的静态方法
js
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
running() {
console.log(this.name + " running~")
}
eating() {
console.log(this.name + " eating~")
}
personMethod() {
console.log("处理逻辑1")
console.log("处理逻辑2")
console.log("处理逻辑3")
}
static staticMethod() {
console.log("PersonStaticMethod")
}
}
// Student称之为子类(派生类)
class Student extends Person {
// JS引擎在解析子类的时候就有要求, 如果我们有实现继承
// 那么子类的构造方法中, 在使用this之前
constructor(name, age, sno) {
super(name, age)
this.sno = sno
}
studying() {
console.log(this.name + " studying~")
}
// 类对父类的方法的重写
running() {
console.log("student " + this.name + " running")
}
// 重写personMethod方法
personMethod() {
// 复用父类中的处理逻辑
super.personMethod()
console.log("处理逻辑4")
console.log("处理逻辑5")
console.log("处理逻辑6")
}
// 重写静态方法
static staticMethod() {
super.staticMethod()
console.log("StudentStaticMethod")
}
}
var stu = new Student("why", 18, 111)
console.log(stu)
// console.log(Object.getOwnPropertyDescriptors(stu.__proto__))
// console.log(Object.getOwnPropertyDescriptors(stu.__proto__.__proto__))
stu.eating()
stu.running()
stu.personMethod()
Student.staticMethod()
console.log(Object.getOwnPropertyDescriptors(Person))
3.1 类继承自内置
- 新创建一个类继承自内置类
- 重写或者拓展内置类的方法
js
class HYArray extends Array {
firstItem() {
return this[0]
}
lastItem() {
return this[this.length-1]
}
}
var arr = new HYArray(1, 2, 3)
console.log(arr.firstItem())
console.log(arr.lastItem())
3.2 类继承混入效果
- 本质
- 实现函数导出一个新的类, 继承自传入类
- 可以配合函数柯里化实现多个类的混入
js
class Person {
}
function mixinRunner(BaseClass) {
class NewClass extends BaseClass {
running() {
console.log("running~")
}
}
return NewClass
}
function mixinEater(BaseClass) {
return class extends BaseClass {
eating() {
console.log("eating~")
}
}
}
// 在JS中类只能有一个父类: 单继承
class Student extends Person {
}
var NewStudent = mixinEater(mixinRunner(Student))
var ns = new NewStudent()
ns.running()
ns.eating()
3.3 类多态
- 定义
- 当对不同的数据类型执行同一个操作时, 如果表现出来的行为(形态)不一样, 那么就是多态的体现.
- 传统的面向对象多态是有三个前提
- 1> 必须有继承(是多态的前提)
- 2> 必须有重写(子类重写父类的方法)
- 3> 必须有父类引用指向子类对象
ts
// 传统的面向对象多态是有三个前提:
// 1> 必须有继承(是多态的前提)
// 2> 必须有重写(子类重写父类的方法)
// 3> 必须有父类引用指向子类对象
// Shape形状
class Shape {
getArea() {}
}
class Rectangle extends Shape {
getArea() {
return 100
}
}
class Circle extends Shape {
getArea() {
return 200
}
}
var r = new Rectangle()
var c = new Circle()
// 多态: 当对不同的数据类型执行同一个操作时, 如果表现出来的行为(形态)不一样, 那么就是多态的体现.
function calcArea(shape: Shape) {
console.log(shape.getArea())
}
calcArea(r)
calcArea(c)
export {}