一、Class基本语法
class和构造函数类似,用于生成新对象。
class Point {
constructor(x, y) {
this.x = x; // 属性
this.y = y;
}
toString() { // 方法
return '(' + this.x + ', ' + this.y + ')';
}
}
- 方法之间不需要逗号分隔,加了分号会报错
- 类的所有方法都定义在类的prototype属性上且内部定义的所有方法都是不可枚举的。
- contructor方法没有写的话会默认添加一个空的constructor方法,constructor方法默认返回实例对象(this),也可以返回另一个对象(A),导致实例对象为该对象(A)。
二、Class特点
1、生成对象
生成实例对象也采用new的方式,如果直接调用会报错。
2、表达式定义
class也可使用表达式的形式定义。
const MyClass = class Me {
getClassName() {
return Me.name;
}
}
该class的名字是MyClass而不是Me,Me只能在Class的内部代码使用,指代当前类,另外使用实例的getClassName方法,得到的也是Me。
let inst = new MyClass();
inst.getClassName(); // Me
Me.name; // referenceError
3、不存在变量提升
Class不存在变脸提升,必须在定义之后使用。
三、Class的继承
1、基本用法
Class可以通过extends方便的实现继承。
在子类的constructor构造函数中必须使用super(…args)(或其他参数)来继承父类的this对象,相当于执行了(constructor(…args))。如果没有constructor方法,那么该方法会被默认添加,并执行super。
- ES5 VS ES6 在类的继承上ES6和ES5有很大不同,ES6中是先创建父类的this对象,子类继承之后,在其上进行改变,而ES5中则是先创建子类的this,再将父类的方法添加到this上。
2、类的prototype属性和proto属性
- 子类的proto属性表示构造函数的继承,指向父类
- 子类prototype属性的proto属性指向父类的prototype属性(和ES5类似,子类的原型对象的proto内部属性指向父类的原型对象)
- Object.getPrototypeOf(子类) === 父类,用于获取父类
3、原生函数的继承
ES5不能实现原生函数的继承,因为在创建了子类的this之后从父类中获取属性和方法,并不能获取到内部的属性和方法。如Array对象的length属性是内部属性,即使创建了子类也不具有length属性。ES6则可以继承原生构造函数定义子类。
四、Class中其他方法
1、getter setter
get propName() {
}
set propName() {
}
定义了这两个方法之后propName的赋值和获取时的行为会改变,执行这两个函数。
2、Genterator方法
Class内部也可以定义Genterator方法
3、静态方法
在方法前加上static,该方法就成为静态方法,静态方法不会被实例继承,而是通过类直接调用(调用方式Foo.classMethod)。父类的静态方法会被子类继承。
4、静态属性
class Foo {
}
Foo.prop = 1;
Foo.prop // 1
ES6中目前只有该方法可定义静态属性
5、new.target
new.target 写在构造函数里,可以用来判断该实例是否是通过new的方式创建的,如果不是该表达式会返回undefined。
class Shape {
constructor() {
if(new.target === Shape) {
}
}
}
五、mixin模式
mixin模式指将多个类合并成一个类,也即多个类的属性和方法的合并。