原型与原型链

90 阅读2分钟

对象的结构

对象中存储属性的区域实际有两个:

  1. 对象自身
    • 比如直接通过对象所添加的属性,位于对象自身中。
    • 在类中通过 x = y 的形式添加的属性,也位于对象自身中。
  2. 原型对象(Prototype)

原型

原型对象(Prototype)

  1. 对象中还有一些内容,会存储到其他的对象里(原型对象)。
  2. 在实例中会有一个属性用来存储原型对象,这个属性叫做___ proto___
  3. 会添加到原型对象中的情况:
    1. 在类中通过 xxx( ){ } 方式添加的方法,位于原型中
    2. 主动向原型中添加属性或方法
  4. 访问原型对象的方法
    • 实例.__proto__
    • Object.getPrototypeOf(对象)
  5. 原型对象中的数据
    1. 实例中的数据(属性、方法等)
    2. constructor(对象的构造函数)
    • 实例.__proto__.constructor

原型链

  1. 原型对象也有原型,这样就构成了一条原型链,根据对象的复杂程度不同,原型链的长度也不同。
    • 实例.__proto__.__proto___
    • 实例的原型链:实例 --> 原型 --> 原型 --> null
    • obj的原型链:obj对象 --> 原型 --> null
  2. 读取对象属性时,会优先查找自身的属性:
 如果对象中有,则使用,没有则去对象的原型中寻找
 如果原型中有,则使用,没有则去原型的原型中寻找
 直到找到Object对象的原型(Object的原型没有原型(null))
 如果找到原型链最后依然没有找到,则会返回undefined

原型链与作用域链区别

  1. 作用域链,是查找变量的链,找不到会报错。
  2. 原型链,是找属性的链,找不到会返回 undefined。

原型链的作用

所有的同类型对象他们的原型对象都是一个,也就意味着,同类型对象的原型链是一样的。

  1. 原型链的作用:相当于是一个公共的区域,可以被所有该类实例访问,可以将一个该类实例中,所有的公共属性(方法)统一存储到原型中,这样我们只需要创建一个属性,即可被所有实例访问。
const p1 = new Person()
const p2 = new Person()

p1 === p2 // false

p1.__proto__ === p2.__proto__ // p1、p2虽然不是同一个对象,但原型是相同的