关于ECMAScript 6中的Class

在传统的 ECMAScript 3 和 ECMAScript 5 版本中,要定义一个类,需要使用function关键字,并采用以下形式。

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

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

var p = new Point(21, 32);
p.toString();

但是从 ECMAScript 6 开始,引入了class关键字来定义类。但是class关键字只是一个语法糖,定义好的类如果使用typeof显示其类型,依旧是function。对于上面示例定义的类,使用新语法就可以定义成以下样子。

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

  toString() {
    return `${this.x},${this.y}`;
  }
}

let p = new Point(21, 32);
p.toString();

其中constructor()方法为整个类的构造方法,类中定义的其他方法都将自动定义在prototype上,方法之间也不需要使用逗号进行分隔。prototype属性在 ES6 中还继续存在,并可以像 ES5 版本中一样使用。如果一个类中没有定义constructor()方法,ES6 会自动向其中添加一个空白的构造方法。constructor()方法默认返回实例对象this,所以也可以根据需要返回另一个对象。

class Person {
  constructor() {
    return Object.create(null);
  }
}

除了直接使用class关键字通过结构方式直接定义类以外,还可以使用函数方式定义类,具体定义方法可以参考以下示例。

const Person = class Me {
  getClassName() {
    return Me.name;
  }
};

示例代码中出现的Me实际上是用来在类定义中指代当前类使用的,注意不是指代this而是指代类本身。因为在使用函数式定义类时,类定义本身并不知道自己要被赋予怎样的一个代号,所以需要在内部自行指定一个代号来代表自己,所以这个Me只能在类定义内部使用。如果类定义内部没有使用到自身,这个Me是可以省略的。