本质上,ES6只是ES5的构造函数的一层包装,所以函数的许多特性都被Class继承,包括name属性,Class和let一样,不存在变量提升。ES6实现了类的继承,类的静态方法,但是目前没有规定类的静态属性,在ES7中,有关于静态属性的提议。
Class类基础
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function Point(x,y){ this.x = x; this.y = y; }
Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }
Class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
|
Class的继承
Class之间可以通过extends关键字实现继承。ES5的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6的继承机制完全不同,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。
1 2 3 4 5 6 7 8 9
| class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return this.color + ' ' + super.toString(); } }
|
类的prototype和proto属性
大多数浏览器的ES5实现之中,每一个对象都有proto属性,指向对应的构造函数的prototype属性。Class作为构造函数的语法糖,同时有prototype属性和proto属性,因此同时存在两条继承链。一、子类的proto属性,表示构造函数的继承,总是指向父类。二、子类prototype属性的proto属性,表示方法的继承,总是指向父类的prototype属性。
1 2 3 4
| class A {} class B extends A {} B.__proto__ === A B.prototype.__proto__ === A.prototype
|
Class的静态方法
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。父类的静态方法,可以被子类继承。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Foo { static classMethod() { return 'hello'; } } Foo.classMethod()
var foo = new Foo(); foo.classMethod()
Class Bar extends Foo{ static classMethod() { return super.classMethod()+'too'; } } Bar.classMethod()
|