概述
继承的实现和js的原型
类
// 类
class Student {
constructor(name, number) {
this.name = name
this.number = number
}
sayHi() {
console.log(
`姓名 ${this.name} ,学号 ${this.number}`
)
}
}
// 通过类 new 对象/实例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()
const madongmei = new Student('马冬梅', 101)
console.log(madongmei.name)
console.log(madongmei.number)
madongmei.sayHi()
用类实现继承
// 父类
class People {
constructor(name) {
this.name = name
}
eat() {
console.log(`${this.name} eat something`)
}
}
// 子类
class Student extends People {
constructor(name, number) {
super(name)
this.number = number
}
sayHi() {
console.log(`姓名 ${this.name} 学号 ${this.number}`)
}
}
// 子类
class Teacher extends People {
constructor(name, major) {
super(name)
this.major = major
}
teach() {
console.log(`${this.name} 教授 ${this.major}`)
}
}
// 实例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()
xialuo.eat()
// 实例
const wanglaoshi = new Teacher('王老师', '语文')
console.log(wanglaoshi.name)
console.log(wanglaoshi.major)
wanglaoshi.teach()
wanglaoshi.eat()
原型关系
// class实际上是函数,可见是语法糖
typeof People // 'function'
typeof Student // 'function'
// 隐式原型和显式原型
console.log(xialuo.__proto__)
/**
* People
* constructor: class Student
* sayHi: ƒ sayHi()
* [[Prototype]]: Object
*/
console.log(Student.prototype)
/**
* People
* constructor: class Student
* sayHi: ƒ sayHi()
* [[Prototype]]: Object
*/
console.log(xialuo.__proto__ === Student.prototype) // true
每个class都有显式原型 prototype
每个实例都有隐式原型 __proto__
实例的隐式原型 __proto__
指向class的显式原型prototype
基于原型的执行规则
获取属性xialuo.name 或执行方法xialuo.sayhi()时
先在自身属性和方法找
如果找不到则去__proto__
中找
执行原型上的方法
xialuo.__proto__.sayHi()
// 输出 undefined。 因为原型上没有相应的属性
xialuo.sayHi()
// 执行类似于 xialuo.__proto__.sayHi.call(xialuo)