本文同步自我得博客:http://www.joeray61.com

简介

ES6Classes是在原型链继承的基础上,由语言本身提供的语法糖,并非是一种全新的继承模式。这使得Javascript有一种更加简洁清晰的方式来实现类的创建和继承。

语法

话不多说,直接上代码。

定义Class

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}

继承Class

class Student extends Person {
    constructor(name, age, grade) {
        super(name, age);
        this.grade = grade;
    }
}

原型链方法

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    speak() {
        console.log('something...');
    }
}

speak就是原型链方法,不需要再繁琐地使用prototype来定义,直接定义在class内部即可。

静态方法

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    static getClassName() {
        return 'Person';
    }
}
console.log(Person.getClassName());    // Person

静态方法直接用类名来调用就可以了,熟悉面向对象编程的同学应该都不陌生。

Species

某些情况下,类里面有一个方法返回的是类的实例,但是你可能希望返回父类的示例,这时候可以使用species pattern来达到目的。

举个栗子,你实现了一个类叫做MyArray,继承自Array,如果你不使用species pattern,那么调用map方法将会返回MyArray的实例,如果使用了species pattern则能够返回Array的实例。

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

Mixin

mixin是类的模板。在EcmaScript中,一个类不能继承多个类。这样有些需求就不是很方便。为了解决这个问题,可以使用mixin。

var Bar = Sub => class extends Sub {
    bar() {}
};

var Baz = Sub => class extends Sub {
    baz() {}
};

class Person {
    speak() {}
}

class Student extends Bar(Baz(Person)) {}

这样,Student就可以继承BarBazPerson3个基类了。

特点

提升

以前使用function来定义类的时候,我们可以在定以前先使用new,由于JS语言的变量提升特性,这样写不会有任何问题,示例如下:

var joe = new Person('joe', 23);
function Person(name, age) {
    this.name = name;
    this.age = age;
}

如果使用class来定义类,则必须在定义后才能使用new来进行对象的实例化,如果先new则会报错

var joe = new Person('joe', 23);    // ReferenceError
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}

严格模式(strict mode)

类声明和类表达式都是在严格模式下执行的。

类表达式

function一样,class也可以使用表达式来定义。类表达式可以命名也可以匿名。当类表达式有命名时,该命名仅作为类内部使用。

var Person = class Man {
    getName() {
        return Man.name;
    }
};
var p = new Person();
console.log(p.getName());    // Man
console.log(Man);    // ReferenceError: Man is not defined

参考资料


JoeRay61
2.3k 声望182 粉丝