1

es6 类-class

与大多正规的面向对象编程语言不同(比如java),js在创建之初就不支持类。js的面向对象编程实现方式是通过构造函数和原型来实现的。

我之前以为es6引入类的概念将会带给这门语言极大的改变。后来才发现es6类的特性只是一种语法糖,使得js创建自定义类型和传统的面向对象语言语法上更为相似,其内部机理和之前构造函数-原型模式本质上是一样的。但是,es6 类的特性依然是值得掌握的,它使得js语言更加的严谨,消除了一些可能导致出错的状况。

语法

类的创建依赖于class和constructor两个关键字,下面介绍下类创建的语法。

创建自定义类型

看下面一段代码:

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

上面代码使用class创建了一个自定义类型Person,constructor是这个类的构造器,sayName是类的公共方法。它和下面一段代码是等价的。

function Person(name, age){
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function(){
    console.log(this.name);
}

二者在使用上完全相同,比如:创建一个Person的实例 new Person('icode007')等。一些小的差别主要有下面几点:

  • 使用class创建的类只能使用new来调用,而后者可以作为普通函数调用。
  • class没有声明提升,后者作为函数会有声明提升。
  • 类声明中的代码自动运行在严格模式下。
  • 类的所有方法都是不可枚举的。

类表达式

与函数类似,类也具有两种形式,类声明和类表达式。

let Person = class{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    sayName(){
        console.log(this.name);
    }
}

let person = new Person('icode007');

类表达式在使用上与类声明几乎没有区别。

类的访问器属性

使用get和set关键字可以为类定义访问器属性。

let Person = class{
    constructor(firstname, lastname){
        this.firstname = firstname;
        this.lastname = lastname;
    }
    get fullname(){
        return this.firstname + this.lastname;
    }
    set fullname(name){
        var arr = name.split(' ');
        this.firstname = arr[0];
        this.lastname = arr[arr.length - 1];
    }
}
let person = new Person('nicholas', 'zakas');
console.log(person.fullname);

类的静态成员

要定义类的静态方法,只需要在公共方法定义前加static关键字即可。如:

let Person = class{
    constructor(firstname, lastname){
        this.firstname = firstname;
        this.lastname = lastname;
    }
    static getFullname(){
        return this.firstname + this.lastname;
    }
}

要使用该静态方法,需要直接在类上调用,比如Person.getFullname()

类的继承

es6的类使用extends来实现继承。例如:

class Rectangle{
    constructor(length,width){
        this.length = length;
        this.width = width;
    }
    getArea(){
        return this.length * this.width;
    }
}

class Square extends Rectangle {
    constructor(length){
        super(length, length);
    }
    getPerimeter(){
        return this.length * 4;
    }
}
var sqr = new Square(5);
console.log(sqr.getArea()

上面代码中,类Square继承了Rectangle类,所以实例sqr同样具有getArea()方法。 同时sqr添加了自己的getPerimeter方法。并重写了构造器constructor。

注意事项

在使用类继承的实现中,需要注意的点是:

  • 如果子类没有重写constructor方法,默认会调用父类的构造器方法。
  • 如果重写了constructor方法,那么需要显式的调用父类的构造器方法,即super(arg...),并且super()调用一定要放到构造器的最前面(准确的说是在使用this前需要调用super)。
  • 父类的静态成员同样会被继承到子类上。

最佳实践

es6的类的语法比较易于掌握,推荐在实际开发中,多使用class来创建自定义类型。 首先会使关于类的信息都包裹在一个class{}中,也会使得js中的类与其他语言的类的语法更加的统一。

更多关于es6的内容,可以关注右侧专栏 - 学习ES6。


charsandrew
201 声望32 粉丝

前端工程师,js开发者,对世界充满好奇,觉得自己永远是个小伙子。


« 上一篇
es6 - Promise