什么是原型?什么是原型链?
原型
原型: 函数天生自带的对象存储空间, 就是为了向里面添加方法, 给所有实例对象使用
原型链
原型链: 从任何一个数据类型出发, 使用 __proto__ 串联起来的对象链状结构, 就叫做 原型链
作用: 为了对象访问机制服务
当你访问一个对象的成员的时候, 首先在对象自己身上查找
如果自己有, 就直接使用, 停止查找
如果没有, 就自动去 __proto__ 上查找, 如果有, 使用, 停止查找
如果还没有, 就按照原型链结构继续去 __proto__ 上查找
以此类推
最终一定能找到 顶级原型(Object.prototype) 都没有
返回 undefined
原型链详细图解
1. 每一个函数天生自带一个属性, 叫做 prototype, 是一个对象数据类型
2. 每一个对象天生自带一个属性, 叫做 __proto__, 指向所属构造函数的 prototype
3. 纯粹的对象数据类型, 都是 Object 内置构造函数的实例
原理详解(结合上图进行思考)
首先,先定义一个构造函数
问题1: p 的 __proto__ 指向了谁 ?
=> 根据概念, 指向所属构造函数的 prototype
=> 因为 p 是 Person 的实例, 所以 p 所属的构造函数就是 Person
=> p.__proto__ === Person.prototype
问题2: Person 的 __proto__ 指向了谁 ?
=> 当你访问 Person.__proto__ 的时候, 是把 Person 当做一个对象来看待
=> 根据概念, 指向所属构造函数的 prototype
=> 在 JS 内, 所有的函数数据类型, 都是 内置构造函数 Function 的实例对象
=> 因为 Person 本质就是一个函数, 所以 Person 就是 Function 的实例对象
=> Person.__proto__ === Function.prototype
问题3: Person.prototpye 的 __proto__ 指向了谁 ?
=> Person.prototype 是一个对象, 只要是对象就有 __proto__
=> Person.prototype 是一个纯粹的对象
=> 纯粹的对象, 都是内置构造函数 Object 的实例
=> Person.prototype 的所属构造函数 就是 Object
=> Person.prototype.__proto__ === Object.prototype
问题4: Function.prototype 的 __proto__ 指向了谁 ?
=> Function.prototype 是一个对象, 只要是对象就有 __proto__
=> Function.prototype 是一个纯粹的对象
=> 纯粹的对象, 都是内置构造函数 Object 的实例
=> Function.prototype.__proto__ === Object.prototype
问题5: Function 的 __proto__ 指向了谁 ?
=> 内置构造函数 Function 是一个函数, 函数本身也是一个对象, 只要是对象就有 __proto__
=> 在 JS 内, 只要是函数, 就是 Function 的实例
=> 内置构造函数 Function 也是函数, 所以也是 Function 的实例
=> 在 JS 内, Function 自己是自己的实例, 自己是自己所属的构造函数
=> Function 所属的构造函数就是 Function
=> Function.__proto__ === Function.prototype
=> Function 叫做顶级函数
问题6: Object.prototype 的 __proto__ 指向了谁 ?
=> Object.prototype 是一个对象, 只要是对象就有 __proto__
=> Object.prototype 的 __proto__ 是 null
=> 因为我们管 Object.prototype 叫做 顶级原型
问题7: Object 的 __proto__ 指向了谁 ?
=> 内置构造函数 Object 是一个函数, 函数本身也是一个对象, 只要是对象就有 __proto__
=> 在 JS 内, 只要是函数就是 Function 的实例
=> Object 是一个内置构造函数, 也是函数, 也是 Function 的实例
=> Object 所属的构造函数也是 Function
=> Object.__proto__ === Function.prototype