基本语法
es6中引入了class的概念,通过class关键字,可以定义一个类。如下:
1 2 3 4 5 6 7 8 9 10 11
| class Blog { constructor (title, author) { this.title = title, this.author = author } publish () { console.log(`${this.author}发布了${this.title}!`) } }
|
关于es6的class语法,有下面几点需要知晓:
- ES6的class只是一种语法糖,它的绝大部分功能,es5都可以做到。
- 定义方法时,不需要加function关键字。
- 方法之间不需要用逗号分隔,加了会报错。
- 类中的所有方法,都定义在原型对象上。
- constructor方法默认返回实例对象,即this
class的继承
类似与传统的面向对象语言,es6的calss之间可以通过extends
关键字来实现继承。
下面让Dog类继承了Animal类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Animal { constructor (name, age) { this.name = name; this.age = age; } speak () { console.log(`I am ${this.name}`); } } class Dog extends Animal { constructor (name, age, color) { super(name, age); this.color = color; } } const dog1 = new Dog('xwj', 21, 'gray'); dog1.speak();
|
在实现继承的时候,要注意以下几点:
- 子类没有自己的this对象,而是继承父类的this对象,然后对其加工并返回。
- 所以子类必须在constructor对象中调用super方法,且必须在构造方法第一行调用。否则得不到this对象,也无法在后面代码中使用this对象。
- ES5的继承,实际上是创造子类的实例对象this,然后将父类方法添加到this上面。
另外,如果没有显示定义constructor方法,这个方法会被默认添加:
1 2 3
| constructor (...args) { super(...args); }
|
super关键字
super在子类中,既可以当作父类构造方法来使用,也可以当作父类原型对象来调用。
1 2 3 4 5 6 7 8 9 10 11 12
| class Super { print () { console.log('super') } } class Sub extends Super { constructor () { super(); super.print(); } }
|
原生构造函数的继承
js中有一些原生的构造函数,比如Array(), String(), Date()等。
如果我们想继承这些原生的构造函数,在es5中是无法实现的,这是因为es5的继承总是先创建子类实例对象this,然后再用父类的构造函数修饰this对象。
而原生构造函数的this恰恰无法通过apply或者call来动态绑定,这导致子类实例拿不到原生构造函中的内部属性。
下面是继承失败的案例:
1 2 3 4 5 6 7 8
| function MyArray () { Array.apply(this, arguments); } MyArray.prototype = new Array(); var arr = new MyArray(1,2,3); arr.pop();
|
但是es6允许继承原生的构造函数,因为es6是先创建父类的实例对象this,然后再用子类的构造函数修饰this。
1 2 3 4 5 6 7
| class MyArray extends Array { constructor (...args) { super(...args); } } let arr = new MyArray(1,2,3); arr.pop();
|
class的getter和setter
和es5一样,在class内部可以使用get
和set
函数来拦截属性的存取行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Person { constructor (name, age) { this._name = name; this._age = age; } get age () { return this._age - 10; } set age (value) { this._age = value; } } let hyy = new Person ('hyy', 21); hyy.age = 20; console.log(hyy.age);
|
静态方法
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。
如果在一个方法前,加上static
关键字,那么这个方法就成为了静态方法,只能通过类名来调用。
1 2 3 4 5 6
| class Animal { static eat () { console.log('Animal like to eat food') } } Animal.eat();
|
另外,父类的静态方法,会被子类继承,并且可以从super关键字上来调用。
静态属性
es6规定,class内部只有静态方法,没有静态属性。
如果想定义静态属性,这有下面这种方式可行。
1 2 3 4
| class Animal { } Animal.love = 'food';
|
最后
关于es6的class,就先总结到这里。更详细的讲解可以看阮一峰老师的教程。