对象扩展

我们都知道JavaScript的面向对象和继承等特性是通过原型Prototype实现的,这和大部分主流语言不同,原型机制设计造成了JavaScript中有很多与众不同(甚至乍一看有些诡异)的特性,很多人学习使用时都感到十分反直觉。不过ES6中又引入了class关键字,能够让熟悉主流语言的程序员感到亲切。

class定义类

实际上,class仅仅是ES6引入的一个语法糖,JavaScript面向对象的本质还是原型对象机制。回顾ES5中,我们会编写类似如下的代码,通过原型机制模拟一个类(注意是定义一个能实例化的“类”,而不是直接定义一个“对象”)。

function Point(x, y) {
    this.x = x;
    this.y = y;
}

Point.prototype.toString = function () {
    return '(' + this.x + ',' + this.y + ')';
};

let p = new Point(1, 2);
console.log(p.toString());

在ES6中,我们可以编写以下等价代码。

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    toString() {
        return '(' + this.x + ',' + this.y + ')';
    }
}

let p = new Point(1, 2);
console.log(p.toString());

这里我们使用了ES6的class关键字,实际上代码运行的结果和ES5的写法是完全相同的,我们定义的toString()方法还是定义在prototype对象上的。

静态方法

ES6中我们可以用static关键字定义一个静态方法,静态方法不能在类的实例上调用,只能通过类名调用。

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    static createPoint(x, y) {
        return new Point(x, y);
    }

    toString() {
        return '(' + this.x + ',' + this.y + ')';
    }
}

静态属性

ES6中可以用如下方式定义静态属性。

class Point {
    ...//Point类的定义
}
//定义静态属性
Point.i = 1;

静态属性调用时也只能通过类名进行调用。

注意:定义静态属性只有上面一种写法,比如试图把i写在class定义内部之类的写法都不行,这是ES6语法对class关键字规定的。

extends实现类的继承

和主流语言差不多,现在ES6中也可以使用extends关键字实现继承了。派生类的构造函数中可以通过super()调用父类构造函数,此外派生类也支持覆盖父类的同名方法。

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    toString() {
        return '(' + this.x + ',' + this.y + ')';
    }
}

class ColorPoint extends Point{
    constructor(x, y, color) {
        super(x, y);
        this.color = color;
    }

    toString() {
        return '(' + this.x + ',' + this.y + ',' + this.color + ')';
    }
}

let c = new ColorPoint(1, 2, 'RED');
console.log(c.toString());
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。