JavaScript的对象模型是基于原型实现的,特点是简单,缺点是理解起来比传统的类-实例模型要困难,最大的缺点是继承的实现需要编写大量代码,并且需要正确实现原型链。ES6中引入了class关键字,让类的定义更加方便。
一、类的声明
1、声明一个类(类声明不允许声明已经生成的类, 否则会报错), 类的声明不会提前(所以要在使用类之前声明)
const people = new People(); //此时会报错
class People {};

class People {};
class People{}; // People 已经声明, 再次声明会报错

2、类声明体在严格模式下运行
class People {
//采用严格模式('use strict')
constructor(name, gender) {
//构造函数(类的默认函数, 如果没有显示定义, 会默认添加一个constructor函数), 通过 new 的实例会自动调用这个函数
this.name = name; //与构造函数相同, 类的 this 指向调用它的实例
this.gender = gender;
}
}
3、1)类的所有方法都定义在类的prototype属性上(即原型链上)
2)类的内部所有方法都是不可枚举的
3)在类的实例上调用方法, 其实就是在调用原型上的方法
class People {
sayHello() {
console.log('Hello, ' + this.name);
}
showGender() {
console.log('You gender is ' + this.gender + 'in instance');
}
}

4、静态方法和静态属性
1)静态方法的定义:
class People {
//方法前加上 static 关键字(静态方法)
static showGender() {
console.log('My gender is ' + this.gender + 'in static');
} //静态方法不会被实例继承, 只能通过类的本身去调用(People.showGender()调用), 但可以被子类继承(通过 extends 继承)
}
注:静态方法中的this指向的是People!所以这里的this.gender === People.gender
2)静态属性的定义
/* 方法一 */
class People {
//通过关键字 static 写入类的定义中, 而不是 constructor 函数中
static gender = '男'; //静态属性与静态方法一样,不会被实例继承, 只能通过类去调用(People.gender), 但可以被子类继承
constructor() {}
};
/* 方法二 */
People.gender = '男';

3)使用方式
People.showGender();
const gender = People.gender;
//或
const gender = People['gender'];
5、name属性返回的是class的类名
console.log(People.name); //(People)
二、类的继承
1、类通过extends方法实现继承
class Student extends People {}
2、显示定义constructor函数时, 必须调用super()方法, 否则会报错
class Student extends People {
constructor() {
super(); //这里不调用 super 会报错
}
}

3、super既可以当做函数使用, 也可以作为对象使用
class Student extends People {
constructor(name, gender, grade) {
super(name, gender); // super 函数这里表示调用父类的构造函数
this.grade = grade; //只有调用了 super 函数以后, 才可以使用this关键字, 否则会报错
console.log(super.gender); // super 对象无法通过 super 调用父类的属性(undefined)
}
showGender() {
super.showGender(); // super 作为对象使用, 指向父类的原型对象(调用的为showGender(){})
}
static showGender() {
super.showGender(); //在静态中调用 super, super 指向父类(这里即调用的 People 的静态方法(static showGender(){}), 这里与普通方法不同)
}
sayGrade() {
console.log('My grade is ' + this.grade);
}
}
const Jom = new Student('Jom', 'Man', 90); //undefined (Student类constructor函数中console.log(super.gender)的结果)
Student.showGender(); //My gender is 男 static;
Jom.showGender(); //My gender is Man instance;
Jom.sayGrade(); //My grade is 90;
三、其他小知识
1、类的数据类型为函数
console.log(typeof People); //Function
2、类的本身就指向构造函数
console.log(People === People.prototype.constructor); //true
3、class同时有 prototype 属性和 proto 属性。

4、子类的 proto 属性总指向父类
console.log(Student.__proto__ === People); //true
5、子类的 prototype 属性的 proto 总指向父类的 prototype 属性
console.log(Student.prototype.__proto__ === People.prototype); //true
本文深入解析ES6中Class语法的使用,包括类的声明、继承及特殊属性。详细介绍构造函数、静态方法、super关键字的用法,以及类与原型的关系。
818

被折叠的 条评论
为什么被折叠?



