class继承

class People {    constructor(name, age) {        this.name = name        this.age = age    }    eat() {        console.log('I can eat')    }}class Student extends People{    constructor(name, age, xuehao) {        super(name, age)        this.xuehao = xuehao    }    read() {        console.log('I read')    }}const xiaoming = new Student('小明', 16, 8888)console.log(xiaoming)xiaoming.eat()  // I can eatxiaoming.read() // I read

原型链继承

function People(name, age) {    if (name) this.name = name    if (age) this.age = age}People.prototype.eat = function() {    console.log('I can Eat')}function Student(name, age, xuehao) {    People.call(this, name, age)    this.xuehao = xuehao}/** * 通过将构造函数(Student)的原型(prototype)指向另一个对象(People)的实例, * 这是实现原型链继承的最佳技术计划。 *  */ Student.prototype = new People()/** * 然而这样做了之后,Student.prototype.constructor的值就变了,不再是Student了。 * 所以须要通过Object.defineProperty办法将Student.prototype上的constructor再改成Student。 * 其实,当Student.prototype = new People()执行后,Student.prototype是People的一个实例, * Student.prototype自身没有constructor属性,Student.prototype.constructor其实会去原型链下来找,也就是: * Student.prototype.constructor  * === Student.prototype.__proto__.constructor  * === People.prototype.construcctor === People * (实例的隐式原型__proto__等于其构造函数的显式原型prototype,所以有Student.prototype.__proto__ === People.prototype) * (而构造函数People的显式原型属性prototype上的constructor指向自身,所以有People.prototype.construcctor === People) */Object.defineProperty(Student.prototype, 'constructor', {    enumerable: false,    value: Student,    writable: true})Student.prototype.read2 = function() {    console.log('I read')}const xialuo = new Student('着落', 17, 6666)console.log(xialuo)xialuo.eat()  // I can eatxialuo.read2() // I read