以前类我们通过构造函数
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }; var p = new Point(1, 2);
ES6可以通过class,完全可以看做构造函数的另一种写法
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } } typeof Point // "function" Point === Point.prototype.constructor // true
let point = new Point(2,3)
构造函数的prototype
属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype
属性上面。
class Point { constructor() { // ... } toString() { // ... } toValue() { // ... } } // 等同于 Point.prototype = { constructor() {}, toString() {}, toValue() {}, };
类中定义的所有方法都是不可枚举的。ES5原型中写的方法是可枚举的。
取值函数(getter)和存值函数(setter)
在“类”的内部可以使用get
和set
关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。
class CustomHTMLElement { constructor(element) { this.element = element; } get html() { return this.element.innerHTML; } set html(value) { this.element.innerHTML = value; } } var descriptor = Object.getOwnPropertyDescriptor( CustomHTMLElement.prototype, "html" ); "get" in descriptor // true "set" in descriptor // true
Class 表达式
const MyClass = class Me { getClassName() { return Me.name; } };
这个类名Me只能在Class内部使用,指代当前类。在外部只能用MyClass
let inst = new MyClass(); inst.getClassName() // Me Me.name // ReferenceError: Me is not defined
若内部没用到类名也可以如下形式
const MyClass = class { /* ... */ };
采用 Class 表达式,可以写出立即执行的 Class。
let person = new class { constructor(name) { this.name = name; } sayName() { console.log(this.name); } }('张三'); person.sayName(); // "张三"
注意
- 类和模块内部默认是严格模式
- 类不存在变量提升
- 类知识构造函数的一层包装,所以函数的许多特性都被Class继承,包括name属性
- Generator方法,若某个方法前加上*,就表示该方法是一个Generator函数
- 类内部this默认指向类的实例。
静态方法
在方法面前加上static该方法就不会被实例继承,而是直接通过类来调用。
class Foo { static classMethod() { return 'hello'; } } Foo.classMethod() // 'hello' var foo = new Foo(); foo.classMethod() // TypeError: foo.classMethod is not a function
静态方法中的this指的是类而不是实例
实例属性的新写法
实例属性除了定义在constructor()
方法里面的this
上面,也可以定义在类的最顶层。
class IncreasingCounter { _count = 0; get value() { console.log('Getting the current value!'); return this._count; } increment() { this._count++; } }
静态属性
静态属性指的是 Class 本身的属性,即Class.propName
,而不是定义在实例对象(this
)上的属性。
class Foo { } Foo.prop = 1; Foo.prop // 1
ES6 明确规定,Class 内部只有静态方法,没有静态属性。现在有一个提案提供了类的静态属性,写法是在实例属性的前面,加上static
关键字。
私有方法和私有属性、new.target属性参考http://es6.ruanyifeng.com/#docs/class