1. 认识class类
在ES6中的新标准定义了class关键字来直接定义类;
但是类的本质上依然是构造函数、原型链的语法糖;
声明类:
可以使用两种方式来声明类:类声明和表达式
class Person {
}
// 类的表达式
var Animal = class {
}
类的特点:
class Person {
}
console.log(Person.prototype) // {}
console.log(Person.prototype.__proto__) // [Object: null prototype] {}
console.log(Person.prototype.constructor) // [class Person]
类的构造方法:
每一个类都有自己的一个构造函数(方法),这个方法的固定名称为constructor;
当我们通过new操作符,操作一个类的时候会调用这个类的构造函数constructor;
每个类只能有一个构造函数,如果包含多个构造函数,会抛出异常;
通过new关键字操作类的时候,会调用constructor函数,执行如下操作:
①在内存中创建一个新的对象;
②这给对象内部的[[prototype]]属性会被赋值为该类的prototype属性;
③构造函数内部的this,会指向创建出来的对象;
④执行构造函数的内部代码(函数体代码);
⑤如果构造函数没有返回非空对象,则返回创建出来的新对象;
class类中的方法定义:
构造方法在new操作符,创建实例时调用,实例方法绑定到原型prototype上,静态方法绑定到类本身上
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~")
}
}
类的静态方法:
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~")
}
// 类的静态方法(类方法)
// 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)
}
}
class中实现继承extends:
super关键字的使用位置:子类的构造函数、实例方法、静态方法;
子类可以重写父类方法并复用父类的方法逻辑;
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("hgf", 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))