通过画图来解释原型链

画一个原型链的图示,并配合代码进行讲解原型链。

我们先给出用于讲解原型链的class案例:

//父类
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}`)
  }
}
//通过类声明对象/实例
const xialuo = new Student('夏洛', 100)

首先,我们先分析一下上面创建的class的类型:

// class 实际上是函数,可见是语法糖
typeof People // 'function'
typeof Student // 'function'

语法糖的解释

(一)在了解了class其实是函数后,我们再了解一下隐式原型显示原型

// 隐式原型和显示原型
console.log(xialuo.__proto__) //xialuo是Student的实例
console.log(Student.prototype)
console.log(xialuo.__proto__ === Student.prototype)

查看打印结果:
通过画图来解释原型链
通过画图来解释原型链

可以得到一个初步的图示:
通过画图来解释原型链

(二)接着,我们再次打印:

console.log(Student.prototype.__proto__)
console.log(People.prototype) //People是Student的父类
console.log(Student.prototype.__proto__ === People.prototype)

通过画图来解释原型链
通过画图来解释原型链
通过画图来解释原型链

因此我们可以得到如下的原型关系

  • 子类的prototype的__proto__指向其父类的prototype

可以得到下图:
通过画图来解释原型链

(三)之后,我们再进一步:

console.log(People.prototype.__proto__)
console.log(Object.prototype)
console.log(People.prototype.__proto__ === Object.prototype)

打印结果如下:
通过画图来解释原型链
通过画图来解释原型链
通过画图来解释原型链

可以得到下图:
通过画图来解释原型链

总结

原型关系

  • 每个class都有显式原型 prototype
  • 每个实例都有隐式原型__proto__
  • 实例的__proto__指向对应class的 prototype

基于原型的执行规则

  • 获取属性xialuo.name或执行方法xialuo.sayHI()时
  • 先在自身属性和方法寻找
  • 如果找不到则自动去__proto__寻找
上一篇:go语言中如何分别通过接口和结构体来分别调用函数


下一篇:原型与原型链