原型链
第一步我们先弄清楚几个概念:
1.js分为函数对象和普通对象,任何对象都有__proto__属性,只有函数对象有prototype属性
2.Object、Function是js的内置函数,类似的还有我们常用到的Array、RegExp、Date、Boolean、Number、String。
3.__proto__是一个对象,它有两个属性,constructor和__proto__.
4.prototype有一个默认的constructor属性,用来指向实例用哪个构造函数创建。
这四条很重要,多读几遍。
下面创建一个例子
function Person(name,age){
this.name = name
this.age = age
}
let person = new Person('张三','20')
js之父在设计js原型、原型链的时候遵从以下两个准则:
1.Person.prototype.constructor == Person // 原型对象的constructor指向构造函数本身
2.person.__proto__ == Person.prototype // 实例的__proto__和原型对象指向同一个地方。
怎么理解上面例子中的Person,Person是构造函数。
如果是函数,它的上一层就是Function,如果是对象,它的上一层就是Object
如果我们需要沿着原型链向上查找,我们就可以 看proto
基于上面的条件,我们推一下下面的。
function Person(name,age){
this.name = name
this.age = age
}
let person = new Person('张三','20')
person.__proto__ == Person.prototype // 准则2
Person.prototype.__proto__ == Object.prototype // 准则2 Person.prototype也是一个对象,对象的上一层就是object
Object.prototype.__proto == null // 原型链到此结束。
Person.prototype.constructor == Person // 准则1
Person.__proto__ = Function.prototype // 准测2
Function.prototype.__proto__ = Object.prototype // 准则2
// **此处注意Person 和 Function的区别, Person是 Function的实例**
// 从中间 function Object()开始分析这一张经典之图
function Object()
let obj = new Object();
obj.__proto__ = Object.prototype; // 准则2
Object.prototype.__proto__ = null; // 原型链到此停止
Object.prototype.constructor = Object; // 准则1
// 所有函数的__proto__ 都和 Function.prototype指向同一个地方
Object.__proto__ = Function.prototype // 准则2 (Object本质也是函数); 概念的第二条
// 此处有点绕
Function.prototype.__proto__ = Object.prototype; // 准则2 (Function.prototype本质也是普通对象,可适用准则2)
Object.prototype.__proto__ = null; // 原型链到此停止
function Function()
Function.__proto__ = Function.prototype // 准则2
Function.prototype.constructor = Function; // 准则1
总结一下:
除了Object的原型对象(Object.prototype)的proto指向null,其他内置函数对象的原型对象(例如:Array.prototype)和自定义构造函数的 proto都指向Object.prototype, 因为原型对象本身是普通对象。