1.使用class定义一个类:类的声明
和类的表达式
//方法一:类的声明
class Person {
}
//方法二:类的表达式
const Student = class {
}
console.log(Person.prototype) //{}
console.log(Object.getOwnPropertyDescriptors(Person.prototype))
// {
// constructor: {
// value: [class Person],
// writable: true,
// enumerable: false,
// configurable: true
// }
// }
console.log(Person.prototype.__proto__)//[Object:null prototype] {}
console.log(Person.prototype.constructor) //[class Person]
console.log(typeof Person) //function
var p = new Person()
console.log(p.__proto__ === Person.prototype) //true
2.类的构造函数
当使用new 调用Person类创建一个对象时,传递的参数如果传递给类?
class Person {
}
var p = new Person('小名', 30)
var s = new Person('小红', 20)
通过new调用类传递的参数
,会作为参数
传递给类的构造函数
定义类的时候,
如果没有明确定义类的构造方法,会使用类的默认的构造方法
如果明确定义了构造方法,就使用定义的构造方法
一个类只有一个构造方法
// 定义类的时候,
// 如果没有明确定义类的构造方法,会使用类的默认的构造方法
// 如果明确定义了构造方法,就使用定义的构造方法
// 一个类只有一个构造方法
class Student {}
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
console.log(Student.constructor); // [Function: Function] 输出类的默认构造方法
console.log(Person.constructor); // [Function: Function]
var p = new Person("小名", 30);
var s = new Person("小红", 20);
console.log(p.name, p.age); //小名 30
console.log(s.name, s.age); //小红 20
当使用new 调用类时,会执行类的构造函数,
调用类时传递的参数,会作为参数传给类的构造函数
class Person {
//constructor为类的构造函数(构造方法)
//类的构造函数被调用时:
//1.在内存中创建一个新对象(空对象)var moni = {}
//2.这个对象内部的[[prototype]]原型对象会指向类的prototype原型对象 moni.__proto__ = Person.prototype
//3.this指向这个对象 this = moni
//4.执行构造函数内部的代码
//5.如果构造函数没有返回非空对象,则返回创建出来的新对象 return moni
constructor(name, age) {
this.name = name
this.age = age
}
}
//当使用new 调用类时,会执行类的构造函数,
//调用类时传递的参数,会作为参数传给类的构造函数
var p = new Person('小名', 30)
var s = new Person('小红', 20)
3.给类的prototype原型对象上添加方法
class Person {
constructor(name, age) {
//定义的属性定义在类的实例上
this.name = name;
this.age = age;
}
//在类的prototype原型对象上添加方法,不可枚举
eatting() {
console.log(this.name + " is eatting");
}
}
var p = new Person("xiaoming", 30);
p.eatting(); //xiaoming is eatting
console.log(p); //Person { name: 'xiaoming', age: 30 }
console.log(Person.prototype); //{} 定义类时,添加到类的prototype原型对象上的方法是不可枚举的
console.log(Object.getOwnPropertyDescriptors(Person.prototype));
// {
// constructor: {
// value: [class Person],
// writable: true,
// enumerable: false,
// configurable: true
// },
// eatting: {
// value: [Function: eatting],
// writable: true,
// enumerable: false,
// configurable: true
// }
// }
相当于下面:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.eatting = function () {
console.log(this.name + " is eatting");
}
4.给类的prototype原型对象上添加访问器方法
class Person {
constructor(name, age) {
//定义的属性定义在类的实例上
this.name = name;
this._age = age;
}
//在类的prototype原型对象上添加方法,不可枚举,被类的实例调用
eatting() {
console.log(this.name + " is eatting");
}
//在类的prototype原型对象上定义访问器方法,不可枚举,被类的实例调用
get age() {
return this.age;
}
set age(newVal) {
this._age = newVal
}
}
var p = new Person('xiaoming', 30)
p.eatting() //xiaoming is eatting
console.log(p) //Person { name: 'xiaoming', _age: 30 }
console.log(Person.prototype) // {}
console.log(Object.getOwnPropertyDescriptors(Person.prototype))
// {
// constructor: {
// value: [class Person],
// writable: true,
// enumerable: false,
// configurable: true
// },
// eatting: {
// value: [Function: eatting],
// writable: true,
// enumerable: false,
// configurable: true
// },
// age: {
// get: [Function: get age],
// set: [Function: set age],
// enumerable: false,
// configurable: true
// }
// }
5.class类中定义静态方法
class Person {
constructor(name, age) {
//定义的属性定义在类的实例上
this.name = name;
this.age = age;
}
//在类的prototype原型对象上添加方法,不可枚举,被类的实例调用
eatting() {
console.log(this.name + " is eatting");
}
//在类上添加静态方法,不可枚举,被类本身调用
static createPerson() {
return new Person("甲", 30);
}
}
var p = new Person("xiaoming", 30);
p.eatting(); //xiaoming is eatting
console.log(p); //Person { name: 'xiaoming', age: 30 }
console.log(Object.getOwnPropertyDescriptors(Person.prototype));
// {
// constructor: {
// value: [class Person],
// writable: true,
// enumerable: false,
// configurable: true
// },
// eatting: {
// value: [Function: eatting],
// writable: true,
// enumerable: false,
// configurable: true
// },
// }
console.log(Person); //[class Person]
console.log(Object.getOwnPropertyDescriptors(Person));
// {
// length: { value: 2, writable: false, enumerable: false, configurable: true },
// prototype: {
// value: {},
// writable: false,
// enumerable: false,
// configurable: false
// },
// createPerson: {
// value: [Function: createPerson],
// writable: true,
// enumerable: false,
// configurable: true
// },
// name: {
// value: 'Person',
// writable: false,
// enumerable: false,
// configurable: true
// }
// }
console.log(Person.createPerson()); //Person { name: '甲', age: 30 }
相当于
function Person (name, age){
this.name = name;
this.age = age;
}
Person.prototype.eatting = function () {
console.log(this.name + " is eatting");
}
Person.createPerson = function () {
return new Person("甲", 30);
}
6.class类中的继承
子类如果实现了继承,在子类构造函数中访问this或return之前必须通过super调用父类构造函数
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
//子类如果实现了继承,在子类构造函数中访问this或return之前必须通过super调用父类构造函数
class Student extends Person {
constructor(name, age, address) {
super(name, age);
this.address = address;
}
}
var stu = new Student('小名', 30, '北京')
console.log(stu) //Student { name: '小名', age: 30, address: '北京' }
console.log(stu.__proto__)//Person {} 输出结果为一个对象,属于Person类
//因为stu.__proto__为Student.prototype,
//而Student.prototype为一个对象,此对象的__proto__原型对象为Person.prototype
//所以Student.prototype为Person类的一个实例对象,即stu.__proto__为一个Person类的一个实例对象
//stu的[[prototype]]原型对象为Person的实例,为[[prototype]]原型对象为Person.prototype原型对象的对象
console.log(stu.__proto__.__proto__ === Person.prototype) //true
子类继承父类的原型对象上的方法和子类继承父类上的静态属性和方法
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
running() {
console.log(this.name + " is running");
}
static createPerson() {
console.log("创建person");
}
}
//子类如果实现了继承,在子类构造函数中访问this或return之前必须通过super调用父类构造函数
class Student extends Person {
constructor(name, age, address) {
super(name, age);
this.address = address;
}
//在子类的原型对象上定义running方法
eatting() {
console.log(this.name + " is eatting");
}
//在子类上定义静态方法
static createStudent() {
console.log("创建student");
}
}
var stu = new Student("小名", 30, "北京");
console.log(stu); //Student { name: '小名', age: 30, address: '北京' }
stu.running(); //小名 is running
stu.eatting(); //小名 is eatting
Student.createStudent(); //创建student
Student.createPerson(); //创建person
console.log(stu.__proto__); //Person {} 为一个Person类的对象,即类Person的一个实例
console.log(Object.getOwnPropertyDescriptors(stu.__proto__));
// {
// constructor: {
// value: [class Student extends Person],
// writable: true,
// enumerable: false,
// configurable: true
// },
// eatting: {
// value: [Function: eatting],
// writable: true,
// enumerable: false,
// configurable: true
// }
// }
//定义子类时,定义在子类prototype原型对象的方法,在子类的prototype对象上
console.log(stu.__proto__.__proto__); //{} 为父类Person类的prototype原型对象
console.log(stu.__proto__.__proto__ === Person.prototype); //true
console.log(Object.getOwnPropertyDescriptors(stu.__proto__.__proto__));
// {
// constructor: {
// value: [class Person],
// writable: true,
// enumerable: false,
// configurable: true
// },
// running: {
// value: [Function: running],
// writable: true,
// enumerable: false,
// configurable: true
// }
// }
// 定义子类时,继承的父类的prototype原型对象上的方法,依然在父类的prototype原型对象上
console.log(Student) //[class Student extends Person]
console.log(Object.getOwnPropertyDescriptors(Student))
// {
// length: { value: 3, writable: false, enumerable: false, configurable: true },
// prototype: {
// value: Person {},
// writable: false,
// enumerable: false,
// configurable: false
// },
// createStudent: {
// value: [Function: createStudent],
// writable: true,
// enumerable: false,
// configurable: true
// },
// name: {
// value: 'Student',
// writable: false,
// enumerable: false,
// configurable: true
// }
// }
console.log(Student.__proto__ === Person) //true
// 因为子类的[[prototype]]原型对象为父类Person,所以可以通过子类Student调用父类Person上的方法
类对父类方法的重写
在子类定义prototype原型对象方法内部,可以通过super调用父类的prototype对象,父类prototype对象上的方法内部的this被绑定为子类prototype原型对象方法内部的this
在子类定义静态方法内部,可以通过super调用父类
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
running() {
console.log(this.name + ' is running')
}
eatting() {
console.log(this.name + ' is eatting')
}
static createPerson() {
console.log('第一步')
}
}
//子类如果实现了继承,在子类构造函数中访问this或return之前必须通过super调用父类构造函数
class Student extends Person {
constructor(name, age, address) {
super(name, age);
this.address = address;
}
//子类对父类方法的重写
eatting() {
console.log('今天吃的很饱')
}
//在子类的原型对象上定义running方法
running() {
//通过super调用父类的原型对象,从父类的原型对象上获取running方法,
//此方法执行时。方法内容的this被绑定为当前作用域的this
super.running()
console.log(this.name + ' run fastest')
}
//在子类上定义静态方法
static createPerson() {
//通过super获取父类,调用父类上的静态方法
super.createPerson()
console.log('第二步')
}
}
var stu = new Student('小名', 30, '北京')
console.log(stu) //Student { name: '小名', age: 30, address: '北京' }
stu.running()
//小名 is running
//小名 run fastest
Student.createPerson()
// 第一步
// 第二步