在 es6 中新出现的 class 关键词可以代替构造函数定义类。

构造函数

// 类名建议大写
function Person(name,age) {
  this.name = name
  this.age = age
}
Person.prototype.say = () => {
  return `我的名字叫${  this.name  }今年${  this.age  }岁了`
}
const obj = new Person('laotie', 88)
console.log(obj.say())      // 我的名字叫 laotie 今年88岁了

class

class Person {               // 定义了一个名字为 Person 的类
  constructor(name,age) {    // constructor 是一个构造方法,用来接收参数
    this.name = name         // this 代表的是实例对象
    this.age = age
  }
  say() {                    // 类的原型对象上的方法,定义在 Person 内,constructor 以外
    return '我的名字叫' + this.name + '今年' + this.age + '岁了'
  }
  static marry() {           // 定义静态方法,该方法不会被继承
    console.log('嫁给我吧')
  }
}
const jerry = new Person('jerry', 88)
console.log(jerry.say())     // 我的名字叫 jerry 今年 88 岁了
if(jerry instanceof Person)  // instanceof 可以判断实例与构造函数的关系

继承使用 extends 关键字:

class Person extends Human {
  constructor() {
    super()      // 构造函数中调用这个方法,才能使用继承的对象中的方法
    super.say()  // 可以调用继承的对象的方法
    ...
  }
}
class Person extends Human {
  private m_name: string;
  private m_age: number;
  constructor(name: string, age: number) {
    this.m_name = name;
    this.m_age = age;
  }

  protected say() {  // protected 保护的属性只能在子类中使用,不能在实例中使用
    console.log('hello');
  }
}

如果要给 Person 的原型对象上增加方法, 需要使用 Object.assign()(如果直接给 Person.prototype 赋值会覆盖对象中原有的属性和方法):

Object.assign(Person.prototype, {
  getName(){...},
  getAge(){...}
})

构造函数、原型与实例之间的关系

我们都知道,js在创建函数的同时,会自动创建一个对应的原型对象,通过 prototype 和 constructor 来建立两者的关系。

class Person{
  constructor(name,age){...}
}
Person.prototype.constructor === Person    //true