1

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 eat
xiaoming.read() // I read

image.png

原型链继承

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 eat
xialuo.read2() // I read

image.png


anchen
21 声望1 粉丝