类 是基于原型的继承的语法糖,类语法不会为JavaScript引入新的面向对象的继承模型
定义类
类语法有两个组成部分:类表达式和类声明
类声明
使用带有class关键字的类名(这里是“Animal”)
class Animal {
constructor(color) {
this.color = color
}
}
提升:类声明不会提升,需要先声明类,然后才能访问它,否则会报错
let p = new Animal(); // ReferenceError
class Animal {}
类表达式
类表达式是定义一个类的一种方式,可以是具名或匿名的
具名类表达式的名称是类内的一个局部属性,可以通过类本身(而不是类实例)的name属性来获取
匿名类
let Animal = class {
constructor(color) {
this.color = color;
}
};
console.log(Animal.name); //Animal
具名类
let Animal = class Animal2 {
constructor(color) {
this.color = color;
}
};
console.log(Animal.name); //Animal
构造函数
constructor方法用于创建和初始化一个由class创建的对象
一个类只能有一个constructor方法,如果一个类有多个constructor,则会报错
一个构造函数可以使用 super 关键字来调用一个父类的构造函数
实例属性
实例的属性必须定义在类的方法里
class Animal {
constructor(color) {
this.color = color
}
}
extends 继承,使用extends创建子类
extends 在类声明或类表达式中,用于创建一个类作为另一个类的一个子类
如果子类中定义了构造函数,那么它必须先调用 super() 才能使用 this
class Animal{
constructor(name){
this.name = name;
}
wang(){
console.log(`${this.name} say hello`);
}
}
class Dog extends Animal{
constructor(name){
super(name); //调用父类构造函数并传入name参数
}
wang(){
console.log(`${this.name} say hello`);
}
}
var d = new Dog('大黄');
d.wang(); //'大黄 say hello'
可以继承基于函数的"类"
function Animal (name) {
this.name = name;
}
Animal.prototype.speak = function () {
console.log(this.name + 'say hello');
}
class Dog extends Animal {
speak() {
super.speak();
console.log(this.name + 'haha');
}
}
var d = new Dog('大黄');
d.speak(); //大黄 say hello haha
重写构造器 species
在子类数组MyArray中返回父类Array对象,使用species覆盖默认的构造函数
例如map()返回默认构造函数的方法时,希望返回的是父Array对象,而不是MyArray对象,使用Symbol.species
class MyArray extends Array{
static get [Symbol.species](){ return Array;}
}
var a = new MyArray(1,2,3);
var mapped = a.map(x => x*x);
console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array); // true
静态方法 static
static 用来定义一个类的一个静态方法,调用静态方法不需要实例化该类
但不能通过一个类实例调用静态方法,静态方法通常用于为一个应用程序创建工具函
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
// 静态方法,可直接调用Point.distance(a, b)
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));
总结
使用类来创建的函数,编写的代码变少了;在类里面,可以清晰的指定构造函数
类需要的所有代码都包含在类声明中,不需要向原型去添加每个方法
class只是语法糖,是原型继承的抽象形式
在创建类的新实例,必须使用关键字new