class 是一种基于原型实现的实现语法糖,为了让面相对象的语法同传统语法一样让程序员更容易接受,让代码更加优雅、可读性更强
class 框架
class ClassName {
// 类的构造函数,可以传递许多参数,一般在 new 的时候调用一次
constructor(x, y) {
// this 是创建的实例,this.attr 是给实例添加 属性
this.attr = x + y;
}
// attr = xx 这样都是将 attr 到当前类的实例(new 后返回的对象)上
instantanceAttr = 200; // 等价于 this.instantanceAttr = 200,
// 这个方法是定义在 实例上的
instanceFn = () => {
// 箭头函数没有自己的 this, 所用到的 this 是宿主环境的
console.log(this, " >>>this");
return this.attr;
};
/**
* 使用 protoFn(){} 是给 当前的类的原型(prototype)上添加 共有的方法,这个是不可枚举的,
* 但是 实例是可以调用的,因为调用的规则是 先找实例身上有没有,
* 有就直接调用,没有就去原型上找,一直找到最顶层的原型为止
*/
protoFn() {
console.log("Parent.prototype.protoFn");
}
/**
* 使用 static 定义的属性或者方法, 直接使用 类名.属性 或者 类名.方法名() 调用
*/
static staticVariable = 100; // 这个是静态属性,直接 类名.staticVariable 调用即可
static staticFn() {
console.log("这个是静态方法,可以直接通过 类名.staticFn() 直接调用");
}
}
ClassName.prototype.protoAttr = "123";
// 实例化一个类对象
const instance = new ClassName(2, 3);
console.log("instance: ", instance);
// 调用 instance 上的 方法
instance.instanceFn();
// 获取 instance 上的 属性
console.log("instance.instantanceAttr: ", instance.instantanceAttr);
// 调用 instance 类原型上的 方法
instance.protoFn();
// 获取 instance 类原型上的属性
console.log("instance.protoAttr: ", instance.protoAttr);
// 调用类的静态 方法
ClassName.staticFn();
// 获取 ClassName 类静态的属性
console.log("ClassName.staticVariable: ", ClassName.staticVariable);
class 说明
- 类是 ES6 的一个语法糖,使得更具传统的面向对象语法、ES5 也是可以做的
- ES6 类的 prototype 依然存在,prototype 对象的 constructor 属性指向类本身
- 与 ES5 一样,类的所有实例共享一个原型对象 即
const inst1 = new ClassName(1,2);
const inst2 = new ClassName(2,3);
console.log(Object.getPrototypeOf(inst1) === Object.getPrototypeOf(inst2)); // true
inst1, inst2 都是 ClassName 的实例,他们的原型都是 ClassName.prototype, 因此 __proto__ 属性也是相同的
- 静态方法不会被继承的
- super 扮演的角色
- 在子类的构造函数中指的是父类的构造函数
- 在子类的普通方法中 super 是父类的原型对象
- 在子类的静态方法中 super 是父类
class Parent {
constructor() {
// 定义在父类的实例属性
this.pNum = 2;
}
// 定义在 Parent.prototype 上的 function
pFn() {
console.log("parent normal fn");
}
// 定义在 Parent.prototype 上的 function
pFn2() {
console.log("parent normal fn2");
}
// 静态方法,只能 Parent.pStaticFn() 调用
static pStaticFn() {
console.log("parent static fn");
}
}
class Son extends Parent {
constructor() {
// 这里的 super 指的是父类的构造函数
super();
// 这里的 super 指的是指向父类的原型对象
super.pFn();
// 因为 super 指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过 super 调用的
console.log("super.pNum: ", super.pNum); // undefined
}
sonFn() {
// 普通方法中的 super 指的是指向父类的原型对象
super.pFn2();
}
static sonStaticFn() {
// 静态方法中的 super 指的是 父类, 而不是父类的原型对象
super.pStaticFn();
}
}
const son = new Son(); // log: parent normal fn
son.sonFn(); // log: parent normal fn2
Son.sonStaticFn(); // log: parent static fn