ES6 Class

JavaScript语言中,生成实例对象的传统方法是通过构造函数

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写法只是对象原型对象的写法更加清晰,更像面向对象编程的语法而已。

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

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

上边代码定义了一个类,可以看到里面有一个constructor()写法,这就是构造方法。而this关键字则代表实例对象。Point类除了构造方法,还定义了一个toString()方法。注意,定义toString()方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去。

 

ES6的类,完全可以看做构造函数的另一种写法

class Point {
   // ...
}

typeof Point   // function
Point === Point.prototype.constructor  // true

上边代码表明,类的数据类型就是函数,类本身就指向构造函数,使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致。

class Bar {
  doStuff() {
    console.log('stuff');
  }
}

const b = new Bar();
b.doStuff() // "stuff"

 

构造函数的prototype属性,在ES6的“类”上边继续存在。事实上,类的所有方法都定义在类的prototype属性上边。

class Point {
  constructor() {
    // ...
  }

  toString() {
    // ...
  }

  toValue() {
    // ...
  }
}

// 等同于
Point.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};

 

因此,在类的实例上边调用方法,其实就是调用原型上的方法

class B {}
const b = new B();

b.constructor === B.prototype.constructor   // true

上边代码中,b是B类的实例,它的constructor()方法就是B类原型的constructor()方法

 

由于类的方法都定义在prototype对象上边,所以类的新方法可以添加在prototype对象上边。Object.assign()方法可以很方便地一次向类添加多个方法。

class Point {
  constructor(){
    // ...
  }
}

Object.assign(Point.prototype, {
  toString(){},
  toValue(){}
});

 

 另外,类的内部所有定义的方法,都是不可枚举的

class Point {
  constructor(x, y) {
    // ...
  }

  toString() {
    // ...
  }
}

Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

上边的代码中,toString()方法是Point类内部定义的方法,它是不可枚举的。

当采用ES5的写法,toString()方法就是可枚举的

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

Point.prototype.toString = function () {
  // ...
};

Object.keys(Point.prototype)
// ["toString"]
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

 

上一篇:Java中获取类的运行时结构


下一篇:ES6 之 Class 类