对象访问机制
上一节的内容:
+ 当你访问一个对象的成员的时候, 会先在自己身上找
+ 自己没有, 去到 __proto__ 上找
+ 再没有, 去到 __proto__ 上找
+ 一直找到顶级对象的 __proto__ 都没有
+ 就返回 undefined
分析:
+ 定义1: 每一个对象都有 __proto__
+ 随便一个实例化对象的 __proto__ 是所属构造函数的 prototype
+ 定义2: 每一个函数都有一个 prototype, 他是一个对象
+ 每一个构造函数的 prototype 应该也有 __proto__
+ 构造函数也是函数, 函数也是一个对象
+ 函数应该也有一个 __proto__, 指向了谁?
function Person(){
this.name = 'Jack'
this.age = 18
this.gender = '男'
}
// 创建一个实例
let p1 = new Person()
定义:
1. 每一个函数天生自带一个属性叫做 prototype, 是一个对象
2. 每一个对象天生自带一个属性叫做 __proto__ 指向所属构造函数的 prototype
3. 当一个对象, 没有准确的构造函数来实例化的时候, 我们都看作是内置构造函数 Object 的实例
例子:
1. var arr = [], Array 的实例
2. var obj = {}, Object 的实例
3. var p1 = new Person(), Person 的实例
4. var time = new Date(), Date 的实例
5. var fn = function(){}, Function 的实例
6. Person.prototype, Object 的实例
7. Array.prototype, Object 的实例
结论:
+ 任何一个对象开始出发
+ **按照 __proto__ 开始向上查找**
+ 最终都能找到 Object.prototype
+ 我们管这个使用 __proto__ 串联起来的对象链状结构, 叫做原型链
+ 原型链作用: 为了对象访问机制服务
注: 只要是函数, 就是大写Function的实例;
内置构造函数 Object 是 内置构造函数 Function 的实例;
顶级对象一定是 Object 的 prototype, 函数的顶级一定是内置构造函数 Function
原型 是每一个函数天生自带的一个对象空间, 在里面写方法是供实例使用的, 多个实例共享该方法
原型链 是使用 __ proto__ 串联起来的对象链状结构, 是为了对象访问机制服务的
它俩完全是两个概念
原型链
+ 从任何一个对象出发, 按照 __proto__ 串联起来的对象链状结构
+ 为了对象访问机制而存在
每一个对象都有原型链
例子 : 数组
+ 数组所属的构造函数是 Array
=> 数组.__proto__ === Array.prototype
=> Array.prototype.__proto__ === Object.prototype
=> 数组.__proto__.__proto__ === Object.prototype
如果我想给 数组 扩展一个方法
+ 写在: Array.prototype 上
+ 例如之前数组常用方法里用它写过, 调用 [].myFilter()
如果我想给 函数 扩展一个方法
+ 写在: Function.prototype 上
+ 调用 fn.xxx(), 类似call, apply, bind 方法
console.log(Array.prototype)
console.log([])
console.log(Object.prototype)
console.log(Object.prototype.__proto__) // null
console.