类的来历
ECMAScript 2015 中引入的 JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖(封装了原型继承相关代码实现的语法糖)。类语法不会为JavaScript引入新的面向对象的继承模型。
类实际上是个“特殊的函数”,就像你能够定义的函数声明和函数表达式一样,类语法有两个组成部分:类声明和类表达式。
什么是类声明:
类声明就是用来定义一个类的一种方法。要声明一个类,你可以使用带有class关键字的类名(这里的类名叫“Kaiji”)。1
2
3
4
5
6class Kaiji {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
注意:
函数声明和类声明之间的一个重要区别是函数声明会提升,类声明不会。你首先需要保证已经声明/定义过你的类,然后才能访问它,否则像下面的代码会抛出一个ReferenceError:1
2
3
4let p = new Kaiji()
// ReferenceError
class Kaiji {}
什么是类表达式:
类表达式就是用来创建/定义一个类的另一种方式。类表达式又分为命名表达式或匿名表达式。其中命名表达式的名称是类主体的本地名称(一般与表达式左边的名字一样)。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/* 匿名类 */
let Kaiji = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
/* 命名的类 */
let Kaiji = class Kaiji {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
注意:
函数表达式和类表达式之间的一个重要区别是函数表达式会提升,类表达式不会。你首先需要保证已经声明/定义过你的类,然后才能访问它,否则像下面的代码会抛出一个
ReferenceError:1
2
3
4let p = new Kaiji()
// ReferenceError
let Kaiji = class Kaiji {}
类由哪些成员构成:
大括号{}内部是用于定义类成员的位置,在大括号{}内部的所有代码包括:构造函数,原型方法,静态方法,getter和setter都在严格模式下执行。
第一个成员:构造函数
构造函数是一个名为:constructor的特殊方法,它主要用于创建和初始化当前类的一个对象。一个类只能拥有一个名为 “constructor”的特殊方法。如果类包含多个constructor的方法,则将抛出 一个SyntaxError
语法错误。1
2
3
4
5
6
7
8
9
10
11class Kaiji {
constructor(height, width) {
this.height = height;
this.width = width;
}
constructor(height, width) {
this.height = height;
this.width = width;
}
// SyntaxError
}
super关键字
super 关键字可以用来 调用超类 ,超类可以理解为(父类/父对象),同时 super 会绑定this指针到父类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Lion extends Cat {
speak() {
// 调用超类(父类)的方法
super.speak();
console.log(this.name + ' roars.');
}
}
第二个成员:原型方法
原型方法就是类内部的一种普通的函数定义,只是它和ES5相比,用了简写的形式1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Kaiji {
// constructor
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea()
}
// 原型方法
calcArea() {
return this.height * this.width;
}
}
const square = new Kaiji(10, 10);
console.log(square.area);
// 100
第三个成员:静态方法
静态方法就是使用 static 关键字定义的函数/方法。值得一提的是调用静态方法不需要实例化该类,同时也不能通过一个类的实例来调用静态方法。静态方法通常用于为一个应用程序创建工具函数。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.hypot(dx, dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
console.log(Point.distance(p1, p2));
类的继承(创建子类)
如果想基于某个基础类 创建一个子类,或者说 想基于某个基础类 继承一个子类 可以使用 extends 关键字在类声明或类表达式中创建一个类作为另一个类的一个子类。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' I am your BaBa');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' I am your Son');
}
}
var d = new Dog('Wang!Wang!');
// 'Wang!Wang! I am your Son'
d.speak();
注意:如果子类中存在构造函数,则需要在使用“this”之前首先调用 super()。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' I am your BaBa');
}
}
class Dog extends Animal {
constructor(name) {
super(name)
this.name = name;
}
speak() {
console.log(this.name + ' I am your Son');
}
}
var d = new Dog('Wang!Wang!');
// 'Wang!Wang! I am your Son'
d.speak();
另外:extends 关键字也可以扩展传统的基于函数的“类”:(也就是通过函数声明创建的类)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function Animal (name) {
this.name = name;
}
Animal.prototype.speak = function () {
console.log(this.name + ' makes a noise.');
}
class Dog extends Animal {
speak() {
super.speak();
console.log(this.name + ' barks.');
}
}
var d = new Dog('Mitzie');
d.speak();
请注意:类不能继承常规(非可构造)对象。(也就是普通对象,如:单例对象 let a = {}
)如果要继承常规对象,可以改用Object.setPrototypeOf():1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var Animal = {
speak() {
console.log(this.name + ' makes a noise.');
}
};
class Dog {
constructor(name) {
this.name = name;
}
}
Object.setPrototypeOf(Dog.prototype, Animal);// If you do not do this you will get a TypeError when you invoke speak
// 如果不这样做,您将在调用speak时得到一个类型错误
var d = new Dog('Mitzie');
d.speak(); // Mitzie makes a noise.
(完)
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Method_definitions