原型链

121 阅读2分钟

原型链

第一步我们先弄清楚几个概念:

1.js分为函数对象和普通对象,任何对象都有__proto__属性,只有函数对象有prototype属性
​
2.ObjectFunction是js的内置函数,类似的还有我们常用到的ArrayRegExpDateBooleanNumberString。
​
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  // 准则2Person.prototype.__proto__ == Object.prototype // 准则2 Person.prototype也是一个对象,对象的上一层就是objectObject.prototype.__proto == null  // 原型链到此结束。Person.prototype.constructor == Person // 准则1Person.__proto__ = Function.prototype // 准测2Function.prototype.__proto__ = Object.prototype  // 准则2// **此处注意Person 和 Function的区别, Person是 Function的实例**
​
​
// 从中间 function Object()开始分析这一张经典之图
function Object()
let obj = new  Object();
​
obj.__proto__ = Object.prototype; // 准则2Object.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, 因为原型对象本身是普通对象。