原型&原型链

926 阅读3分钟

原型:构造函数天生自带的一个prototype 为构造函数添加方法,专门给实例对象使用

四个规则

  1. 引用类型,都具有对象特性,即可自由扩展属性。
  2. 引用类型,都有一个隐式原型 proto 属性,属性值是一个普通的对象。
  3. 引用类型,隐式原型 proto 的属性值指向它的构造函数的显式原型 prototype 属性值。
  4. 当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 proto(也就是它的构造函数的显式原型 prototype)中寻找。

规则一

引用类型,都具有对象特性,即可自由扩展属性:

const obj = {}
const arr = []
const fn = function () {}

obj.a = 1
arr.a = 1
fn.a = 1

console.log(obj.a) // 1
console.log(arr.a) // 1
console.log(fn.a) // 1

规则二

引用类型,都有一个隐式原型 proto 属性,属性值是一个普通的对象:

const obj = {};
const arr = [];
const fn = function() {}

console.log('obj.__proto__', obj.__proto__);
console.log('arr.__proto__', arr.__proto__);
console.log('fn.__proto__', fn.__proto__);

规则三

引用类型,隐式原型 proto 的属性值指向它的构造函数的显式原型 prototype 属性值:

const obj = {};
const arr = [];
const fn = function() {}

obj.__proto__ == Object.prototype // true
arr.__proto__ === Array.prototype // true
fn.__proto__ == Function.prototype // true

规则四

当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 proto(也就是它的构造函数的显式原型 prototype)中寻找:

const obj = { a:1 }
obj.toString
// ƒ toString() { [native code] }

首先, obj 对象并没有 toString 属性,之所以能获取到 toString 属性,是遵循了第四条规则,从它的构造函数 Object 的 prototype 里去获取。

原型链

proto 串联起来的对象链状结构 注意: 使用 proto 每一个对象数据类型, 都有一个属于自己的原型链 作用: 为了访问对象成员

7个问题引出原型链

  1. 实例对象身上的 proto 指向谁?
  • 指向所属构造函数的 prototype
  • p1 所属的构造函数是 Person
  • p1.proto 指向 Person.prototype
  1. Person.prototype 的 proto 指向谁 ?
  • Person.prototype 所属的构造函数是谁
  • 因为 Perosn.prototype 是一个对象数据类型(Object)
  • 在 JS 内所有的 Object 数据类型都是属于 Object 这个内置构造函数
  • Person.prototype 是属于 Object 这个内置构造函数的
  • Person.prototype 的 proto 指向 Object.prototype
  1. Person 的 proto 指向谁 ?
  • Person 是一个函数, 函数本身也是一个对象, 就会有 proto
  • 在 JS 内, 所有的函数都是属于内置构造函数 Function 的实例
  • Person.proto 指向 Function.prototype
  1. Object.prototype 的 proto 指向谁 ?
  • Object.prototype 是一个对象数据类型, 只要是对象, 都是数据 Object 这个内置构造函数的
  • 注意: Object.prototype 在 JS 内叫做顶级原型, 不在有 proto
  • Object.prototype 的 proto 指向 null
  1. Object 的 proto 指向谁 ?
  • Object 是内一个内置构造函数, 同时也是一个函数, 同时也是一个对象
  • 在 JS 内, 所以的函数都是属于内置构造函数 Function 的实例
  • Object 也是 Function 的实例
  • Object.proto 指向 Function.prototype
  1. Function.prototype 的 proto 指向谁 ?
  • Function.prototype 也是一个对象数据类型
  • 只要是对象数据类型都是 Object 的实例
  • Function.prototype 的 proto 指向 Object.prototype
  1. Function 的 proto 指向谁 ?
  • Function 也是一个内置构造函数, 也是一个函数
  • 在 JS 内, 所有的函数都是属于内置构造函数 Function 的实例
  • Function 自己是自己的构造函数
  • Function 自己是自己的实例对象
  • Function 所属的构造函数的是 Function

对象访问机制

  • 当你需要访问对象的成员的时候
  • 首先在自己身上查找, 如果有直接使用
  • 如果没有, 会自动去 proto 上查找
  • 如果还没有, 就再去 proto 上查找
  • 直到 Object.prototype 都没有, 那么返回 undefined

总结

原型链就是一个过程,原型是原型链这个过程中的一个单位,贯穿整个原型链。就好像你要是看完了不点个赞,我可以顺着网线找到你。